/*************************************************************************************
IncTaxCalc.sas -- Calculator for Federal and State Personal Income Taxes
Author: Jon Bakija
Contact: jbakija@williams.edu
Last updated: February 2, 2009
For detailed documentation, see Documentation_IncTaxCalc.doc
***************************************************************************************
*                             INSTRUCTIONS                                            *
***************************************************************************************
Before running this program, go to the very end of the program (Section VI,
"Specify options and run IncTaxCalc macro"), and follow the instructions there.
At the end, you can specify the names of input and output data sets and paths, 
choose how marginal tax rates will be calculated, choose whether to produce a 
detailed output data set, and choose the formats of the input and output data sets,
among other options. A suggested strategy for debugging is outlined in
DebugIncTaxCalc.doc.

***************************************************************************************
*                           OUTLINE OF PROGRAM                                        *
***************************************************************************************
I.   IncTaxCalc macro begins
II.  Specify level of log file detail
III. IncTaxCalc macro establishes pathnames
IV.  Read in tax law parameter data sets
V.   Main body of tax calculator program
	 A.  Read in data set with individual taxpayer characteristics.
     B.  BRACKETREADER macro: runs taxable income through bracket and rate structure 
		 using SAS arrays.  This is invoked repeatedly by FEDTAX and STATETAX macros below.
	 C.  MAKEDATA, ITERATION1, MTRCALC, and CLOSEDATASTEP macros 
		 (1) MAKEDATA macro: Contains the data step that merges tax
			 parameter data with individual taxpayer records, defines a few
			 variables, and sets initial values of many variables to zero. This
			 creates a data set where each record contains the characteristics of
			 an individual taxpayer, along with the federal and state tax parameters
			 that would apply to that taxpayer.  To speed processing, this step uses
			 the "set" statement with the "key = " option, rather than using a merge
			 statement. Creates a temporary data set called TaxResults.
		 (2) ITERATION1 macro: Invokes FEDTAX and STATETAX macros repeatedly to 
			 calculate tax liabilities.  Within ITERATION1, FEDTAX and STATETAX are
			 each invoked up to six times in cases where state tax liability feeds
			 into the determination of federal tax liability and vice versa.  Each
			 invocation of FEDTAX and STATETAX within an iteration is called a "deduction
			 cycle". 
		 (3) DETAIL1 macro: Creates optional detail variables from first iteration.
		 (4) MTRCALC macro: Calculates marginal tax rates.  Contains the following sub-macros.
			 (a) ITERATION2 macro: Re-calculates tax liabilities after adding an increment
				 to variable chosen by user, and then calculates marginal rates.  
				 Within ITERATION2, FEDTAX and STATETAX are each invoked up to six times 
				 in cases where state tax liability feeds into the determination of federal 
				 tax liability and vice versa. 
			 (b) DETAIL2 macro: Creates optional detail variables for 2nd iteration. 
		 	 (c) ITERATION3 macro: Optionally re-calculates marginal rates after subtracting
				 an increment from the initial value of the user chosen variable, if
				 the initial marginal rate exceeds some user-chosen value.  This option
				 is offered because it can help avoid "notches" that create enormous
				 marginal tax rates.  Within ITERATION3, FEDTAX and STATETAX are each invoked 
				 up to six times in cases where state tax liability feeds into the determination
				 of federal tax liability and vice versa. 
			 (d) DETAIL3 macro: Creates optional detail variables for 3rd iteration.
		 (5) NOMTR macro: if incrementquantity = 0, this macro will execute instead of MTRCALC.
			 In this case, marginal tax rates are not calculated and fewer iterations are run.
		 (6) CLOSEDATASTEP macro: Executes statements at the end of the data step.
			 (a) LIABILITY macro: Creates tax liability and average tax rate variables
				 for output data set.
			 (b) KEEPER1 macro: invokes "keep" statement for detailed output, if desired.
			 (c) KEEPER2 macro: invokes "keep" statement for basic output, if desired.
			 (d) CHOOSER macro: Conditionally invokes a KEEPER1 or KEEPER2 depending on 
				 user-selected options (chosen at end of program).  
     D.  FEDTAX macro: performs federal tax calculations.
		 (1) FEDTAX1 macro: calculates taxable income and most credits
		 (2) FEDTAX2 macro: calculates normal tax, alternative capital gains taxes,
			 maximum tax on earned income, minimum tax, and income averaging
		 (3) FEDTAX3 macro: calculates alternative minimum tax
		 (4) FEDTAX4 macro: recalculates FEDTAX2 and FEDTAX3 under a different itemization status
			 if taxpayer is subject to AMT or minimum tax or if the federal itemization decision
			 constrains state itemization decisions.  It then chooses itemization status based on
			 minimization of combined federal and state income tax liability.
		 (5) SWITCHITEM macro: conditionally executes FEDTAX4 only if it is the first iteration of
			 the calculator (before adding an increment to calculate marginal rates).  When ITERATION2
			 and ITERATION3 are invoked, itemization status is held constant at the value it had in the
			 corresponding "deduction cycle" within ITERATION1.  This helps avoid notches.
		 (6) FEDTAX5 macro: calculates various pre-1948 federal provisions
		 (7) FEDYEARSELECTOR macro: conditionally invokes FEDTAX5 depending on yearstart
		 (8) FEDTAX6 macro: calculates federal child credit and final federal tax liability
     E.  STATETAX macro: performs state tax calculations.
		 (1) STATETAX1 macro: performs complete state income tax calculation
		 (2) STATETAX2 macro: if state law constrains state itemization status to depend in some way
		     on federal itemization, the STATETAX2 macro invokes STATETAX1 twice, once for each
			 possible federal itemization status.  The difference in state tax liability with and
			 without federal itemization is then fed back into FEDTAX in the next "deduction
			 cycle," so that it can be taken into account in determining the optimal federal
			 itemization status.
	 F.  OUTDAT macro: creates output data sets.
     G.  INVOKEMACROS macro: invokes the macros from part C above in the appropriate order
VI.  Specify options and run IncTaxCalc macro 
***************************************************************************************/

/********************************************************************************************
*  								I. INCTAXCALC MACRO										    *
*********************************************************************************************/
%macro IncTaxCalc(
programpath= ,
inputpath= ,
outputpath= ,
inputset= , 
outputset= ,
fedparam= ,
stateparam= ,
loadparam= ,
mtrvar= , 
incrementkind= , 
incrementquantity= , 
detail= , 
inputformat= , 
outputformat= ,
reverseMTR= ,
checkMTR= ,
statecodetype= , 
yearstart= , 
cbinclude= ,
local= ) ;
/*******************************************************************************************/

/*******************************************************************************************
*                   II. SPECIFY LEVEL OF LOG FILE DETAIL                                   *
********************************************************************************************/

	/**************** SETTINGS FOR DEBUGGING ************************
	options nomlogic; options nosource; options nonotes; 
	options nospool; options msglevel=n ; options mprint; 
	options linesize=max ;
	****************************************************************/

	/****************** MAXIMUM LOG FILE DETAIL *********************
    options mprint; options mlogic; options source;
    options notes; options msglevel=i ; options fullstimer ; 
    options spool ; options linesize=max ;
	*****************************************************************/

	/****************** MEDIUM LOG FILE DETAIL *********************/
    options nomprint; options nomlogic; options source;
    options notes; options msglevel=i ; options fullstimer ; 
    options spool ; options linesize=max ;
	/****************************************************************/

	/****************** MINIMAL LOG FILE DETAIL *********************
    options nomprint; options nomlogic; options nosource;
    options notes; options msglevel=i ; options fullstimer ; 
    options spool ; options linesize=max ;
	****************************************************************/

/*******************************************************************************************/
/* Restore lines below to facilitate debugging */
PROC PRINTTO LOG=" &outputpath.\IncTaxCalc.log " NEW;
RUN;

/**************************************************************************************
*                           III.  PATHNAMES		                                      *
***************************************************************************************/
/* IncTaxCalc macro establishes necessary libnames and filenames here */

/* PROGRAM DIRECTORY: the path name of the directory where this program is located
goes between the quotes in both lines below */

		libname program " &programpath " ;
		filename programf " &programpath " ;

/* INPUT DIRECTORY: The path name of the directory where your input data set
containing personal information on individual taxpayers is stored goes between
the quotes in both lines below */

		libname taxpyr " &inputpath " ; 
		filename taxpyrf " &inputpath " ;

/* OUTPUT DIRECTORY: The path name of the directory where you want to send the output
data set with individual tax rates and liabilities goes between the quotes in both
lines below */

		libname results " &outputpath " ;
		filename resultsf " &outputpath " ;
/*******************************************************************************************/

/********************************************************************************************
*  						IV. READ TAX PARAMETER DATA SETS	 							    *
*      See documentation for definitions of all tax parameter variables listed below        *
*********************************************************************************************/
%macro readparam ;
%if &loadparam = 1 %then %do ;
  data StateLaw (index=(statekey)) ;
  	length statename $ 12;
	length filertype $ 12;
	length taxtype $ 12;
	length base $ 12;
	length sptx $ 12;
	length sptx2 $ 12;
	length xtaxtype $ 12;
	length xbase $ 12;
	infile programf(&stateparam..dat) end=final EXPANDTABS lrecl=2400 ;
	input
	statename $ stateyear filertype $ soi statekey taxtype $ base $ conform multbrk 
	comprop sepdis mardedtype mardedlim mardedpct cgexpct cgexamt 
	divexpct divexamt intexpct intexamt diexamt expercap exreturn 
	ex_dep ex_age pctex exlim exprorat minstded maxstded minstded_d  
	maxstded_d minstded_a maxstded_a pctstded zba dpthresh1 dpthresh2 
	dprate1 dprate2 crpercap crreturn cred_dep cred_age crphthresh 
	crphrate itemiz charded chlim sitded intded propded saleded medded
	dedfed limfdtype limfdamt limfdamt2 limfdpct asdfed sstxded itemlim
	icredrate idphthresh retextype retex retph1 retph2 retexage pctfdeldcr
	ssbentx lowtype low lowdepamt loweldamt lowph1 lowph2 lowphdep lowminage
	miscextype miscexamt eictypestate eicstate1 eicstate2 eicstate3 bracknum
	b1-b26 r1-r26 sptx $ sptxex sptxrate sptx2 $ sptxex2 sptxrate2 xtaxtype $
	xbase $ xosa1st xcgexpct xdivexamt xdivexpct xintexpct xexpercap 
	xexreturn xex_dep xex_age xpctex xnotaxflr xminstded xmaxstded xpctstded 
	xcrpercap xcrreturn xcred_dep xcred_age xagicrmax xcharded xchlim xdedfed
	xintded xsitded xitemlim xbracknum xb1-xb14 xr1-xr14 mintaxtype mintaxrate
	mintaxex mintaxapp kidcaretype kidcareref kc1 kc2 kc3 kc4 kc5 kc6 itemalloc
	stdalloc exalloc credalloc 
	cbtype cbage cbref cbform cbincdef cbincval1 cbincval2 
	cbmaxhome cbmaxrent cbrenteq cbmaxcr1 cbmaxcr2 
	cbthresh1 cbthresh2 cbthresh3 cbthresh4 cbthresh5 
	cbpct1 cbpct2 cbfloor1 cbfloor2 cbfloor3 cbfloor4 
	xcbrenteq xcbmaxcr1 xcbmaxcr2 xcbthresh1 xcbthresh2 
	xcbthresh3 xcbthresh4 xcbthresh5 xcbpct1 xcbpct2 xcbfloor1 xcbfloor2 localtype localrate ;

	if (stateyear >= &yearstart ) or taxtype="none" ;
  run ;

  data FedLaw (index=(fedkey)) ;
	length filertype $ 8 ;
	length Ftaxtype $ 8 ;
	length Fsptx $ 8 ;
	length Fxtaxtype $ 8 ;
	infile programf(&fedparam..dat) end=final EXPANDTABS lrecl=2400 ;
	input
	Fedyear Filertype $ Fedkey Ftaxtype $ Fmarded Fmultbrk Fcgexpct Fdivexamt
	Fdiexamt Funemp Fssbentax 
	Fssb1 Fssb2 Fssr1 Fssr2
	Fexpercap Fexreturn Fex_dep Fex_age
	Fpctex Fexlim Fminexlim Fexlimrate Fcharded Fchlim Fintded
	Fmedded Fsaleded Fbusexded Fmovexded Fcasdedlim Fidphthresh
	Fidphrate Fminstded Fmaxstded Fminstded_d Fmaxstded_d Fminstded_a
	Fmaxstded_a Fpctstded Fzba Fbracknum Fb1-Fb55 Fr1-Fr55 Fincavg
	Fsptx $ Fsptxex Fsptxrate Fxtaxtype $ Fxcgexpct Fxdivexpct
	Fxexreturn Fxex_dep Fxpctex Fxmaxstded Fxpctstded Fxcred_dep
	Fxintded Fxbracknum Fxb1-Fxb3 Fxr1-Fxr3 Fmaxeitype Fmaxeirate
	Fmintaxtype Fmintaxrate Famttype Famtex Famtexth Famtexrate
	Famtb1 Famtb2 Famtb3 Famtr1 Famtr2 Famtr3 Famtbrkn Fcrpercap
	Fkidc Fkidcthresh Fkidcrate Fkidcrefinc Fkidcrefrate Feicphin0
	Feicphin1 Feicphin2 Feic1bend0 Feic1bend1 Feic1bend2 Feic2bend0
	Feic2bend1 Feic2bend2 Feicphout0 Feicphout1 Feicphout2 Feiclim0
	Feiclim1 Feiclim2 
	Feiciilim
	Fssrate Fsscap Fhirate Fhicap FssrateSE FhirateSE	
	Fkcaretype Feldctype Feldcbase Feldcbase2 Feldcrate Feldcex Feldcex2 
	Feldcagefree ;

	if (Fedyear >= &yearstart ) or Ftaxtype="none" ;

  run ;

%end ;
%mend readparam ;
%readparam ;

/********************************************************************************************
*           A. READ IN DATA SET WITH INDIVIDUAL TAXPAYER CHARACTERISTICS,					*
*              THEN MERGE APPLICABLE TAX LAWS TO EACH TAXPAYER RECORD.						*
*********************************************************************************************/

/* if state is postal code abbreviation */
%macro TextInput1 ;
	data idataset;
      infile taxpyrf(&inputset..dat) end=final EXPANDTABS lrecl=2400 ;
      input
        id year fedyear stateyear state $ filertype $ 
		deps kids1 kids2 kids3 agenum age agesp blind income 
		wagsal1 wagsal2 businc1 businc2 farminc1 farminc2
		ltcg1 ltcg2 othcg1 othcg2 div1 div2 int1 int2 teint1 teint2 
		pension1 pension2 rentinc1 rentinc2 ui1 ui2 ssben1 ssben2 
		partscorp1 partscorp2 othinc1 othinc2 othadj1 othadj2 
		charity charcg intpaid invint stinctax proptax salestax 
		taxnodetail medexp casualty movex busex miscdedlim 
		omiscded childcare fdcred otaxpref oamtadj avglaginc 
		psincome psded rentpay homeval ;
%mend TextInput1 ; 

/* if state is SOI code */
%macro TextInput2 ;
	data idataset;
      infile taxpyrf(&inputset..dat) end=final EXPANDTABS lrecl=2400 ;
      input
        id year fedyear stateyear state filertype $ 
		deps kids1 kids2 kids3 agenum age agesp blind income 
		wagsal1 wagsal2 businc1 businc2 farminc1 farminc2
		ltcg1 ltcg2 othcg1 othcg2 div1 div2 int1 int2 teint1 teint2 
		pension1 pension2 rentinc1 rentinc2 ui1 ui2 ssben1 ssben2 
		partscorp1 partscorp2 othinc1 othinc2 othadj1 othadj2 
		charity charcg intpaid invint stinctax proptax salestax 
		taxnodetail medexp casualty movex busex miscdedlim 
		omiscded childcare fdcred otaxpref oamtadj avglaginc 
		psincome psded rentpay homeval ;
%mend TextInput2 ; 

/* if input data set is permanent SAS data set */
%macro SasInput ;
	data idataset;
      set taxpyr.&inputset ;
%mend SasInput ; 

/* if input data set is temporary SAS data set */
%macro SasInput2 ; 
	data idataset;
      set &inputset ;
%mend SasInput2 ; 

/* if state is postal code abbreviation */
%macro StateTranslate1 ; 
	  statename = state ;

		if statename= 	"zz"	then soi=	0	;
		else if statename= 	"al"	then soi=	1	;
		else if statename= 	"ak"	then soi=	2	;
		else if statename= 	"az"	then soi=	3	;
		else if statename= 	"ar"	then soi=	4	;
		else if statename= 	"ca"	then soi=	5	;
		else if statename= 	"co"	then soi=	6	;
		else if statename= 	"ct"	then soi=	7	;
		else if statename= 	"de"	then soi=	8	;
		else if statename= 	"dc"	then soi=	9	;
		else if statename= 	"fl"	then soi=	10	;
		else if statename= 	"ga"	then soi=	11	;
		else if statename= 	"hi"	then soi=	12	;
		else if statename= 	"id"	then soi=	13	;
		else if statename= 	"il"	then soi=	14	;
		else if statename= 	"in"	then soi=	15	;
		else if statename= 	"ia"	then soi=	16	;
		else if statename= 	"ks"	then soi=	17	;
		else if statename= 	"ky"	then soi=	18	;
		else if statename= 	"la"	then soi=	19	;
		else if statename= 	"me"	then soi=	20	;
		else if statename= 	"md"	then soi=	21	;
		else if statename= 	"ma"	then soi=	22	;
		else if statename= 	"mi"	then soi=	23	;
		else if statename= 	"mn"	then soi=	24	;
		else if statename= 	"ms"	then soi=	25	;
		else if statename= 	"mo"	then soi=	26	;
		else if statename= 	"mt"	then soi=	27	;
		else if statename= 	"ne"	then soi=	28	;
		else if statename= 	"nv"	then soi=	29	;
		else if statename= 	"nh"	then soi=	30	;
		else if statename= 	"nj"	then soi=	31	;
		else if statename= 	"nm"	then soi=	32	;
		else if statename= 	"ny"	then soi=	33	;
		else if statename= 	"nc"	then soi=	34	;
		else if statename= 	"nd"	then soi=	35	;
		else if statename= 	"oh"	then soi=	36	;
		else if statename= 	"ok"	then soi=	37	;
		else if statename= 	"or"	then soi=	38	;
		else if statename= 	"pa"	then soi=	39	;
		else if statename= 	"ri"	then soi=	40	;
		else if statename= 	"sc"	then soi=	41	;
		else if statename= 	"sd"	then soi=	42	;
		else if statename= 	"tn"	then soi=	43	;
		else if statename= 	"tx"	then soi=	44	;
		else if statename= 	"ut"	then soi=	45	;
		else if statename= 	"vt"	then soi=	46	;
		else if statename= 	"va"	then soi=	47	;
		else if statename= 	"wa"	then soi=	48	;
		else if statename= 	"wv"	then soi=	49	;
		else if statename= 	"wi"	then soi=	50	;
		else if statename= 	"wy"	then soi=	51	;
		else soi=0 ;

  	  if filertype="h" then statekey = stateyear*1000 + soi*10 + 1 ;
	  else if filertype="m" then statekey = stateyear*1000 + soi*10 + 2 ;
	  else if filertype="s" then statekey = stateyear*1000 + soi*10 + 3 ;

	  if filertype="h" then fedkey = fedyear*100 + 1 ;
	  else if filertype="m" then fedkey = fedyear*100 + 2 ;
	  else if filertype="s" then fedkey = fedyear*100 + 3 ;

	run ;
%mend StateTranslate1 ; 

/* if state is SOI code */
%macro StateTranslate2 ; 
	  soi = state ;

		if soi=	0	then statename=	"zz"	;
		else if soi=	1	then statename=	"al"	;
		else if soi=	2	then statename=	"ak"	;
		else if soi=	3	then statename=	"az"	;
		else if soi=	4	then statename=	"ar"	;
		else if soi=	5	then statename=	"ca"	;
		else if soi=	6	then statename=	"co"	;
		else if soi=	7	then statename=	"ct"	;
		else if soi=	8	then statename=	"de"	;
		else if soi=	9	then statename=	"dc"	;
		else if soi=	10	then statename=	"fl"	;
		else if soi=	11	then statename=	"ga"	;
		else if soi=	12	then statename=	"hi"	;
		else if soi=	13	then statename=	"id"	;
		else if soi=	14	then statename=	"il"	;
		else if soi=	15	then statename=	"in"	;
		else if soi=	16	then statename=	"ia"	;
		else if soi=	17	then statename=	"ks"	;
		else if soi=	18	then statename=	"ky"	;
		else if soi=	19	then statename=	"la"	;
		else if soi=	20	then statename=	"me"	;
		else if soi=	21	then statename=	"md"	;
		else if soi=	22	then statename=	"ma"	;
		else if soi=	23	then statename=	"mi"	;
		else if soi=	24	then statename=	"mn"	;
		else if soi=	25	then statename=	"ms"	;
		else if soi=	26	then statename=	"mo"	;
		else if soi=	27	then statename=	"mt"	;
		else if soi=	28	then statename=	"ne"	;
		else if soi=	29	then statename=	"nv"	;
		else if soi=	30	then statename=	"nh"	;
		else if soi=	31	then statename=	"nj"	;
		else if soi=	32	then statename=	"nm"	;
		else if soi=	33	then statename=	"ny"	;
		else if soi=	34	then statename=	"nc"	;
		else if soi=	35	then statename=	"nd"	;
		else if soi=	36	then statename=	"oh"	;
		else if soi=	37	then statename=	"ok"	;
		else if soi=	38	then statename=	"or"	;
		else if soi=	39	then statename=	"pa"	;
		else if soi=	40	then statename=	"ri"	;
		else if soi=	41	then statename=	"sc"	;
		else if soi=	42	then statename=	"sd"	;
		else if soi=	43	then statename=	"tn"	;
		else if soi=	44	then statename=	"tx"	;
		else if soi=	45	then statename=	"ut"	;
		else if soi=	46	then statename=	"vt"	;
		else if soi=	47	then statename=	"va"	;
		else if soi=	48	then statename=	"wa"	;
		else if soi=	49	then statename=	"wv"	;
		else if soi=	50	then statename=	"wi"	;
		else if soi=	51	then statename=	"wy"	;
		else statename="zz" ;

  	  if filertype="h" then statekey = stateyear*1000 + soi*10 + 1 ;
	  else if filertype="m" then statekey = stateyear*1000 + soi*10 + 2 ;
	  else if filertype="s" then statekey = stateyear*1000 + soi*10 + 3 ;

	  if filertype="h" then fedkey = fedyear*100 + 1 ;
	  else if filertype="m" then fedkey = fedyear*100 + 2 ;
	  else if filertype="s" then fedkey = fedyear*100 + 3 ;

	run ;
%mend StateTranslate2 ; 


%if &inputformat = 0 %then %do ;
	%if &statecodetype=0 %then %do ;
		%TextInput1 ;
		%StateTranslate1 ;
	%end ;
	%else %if &statecodetype=1 %then %do ;
		%TextInput2 ;
		%StateTranslate2 ;
	%end ;
%end ;
%else %if &inputformat = 1 %then %do ;
	%if &statecodetype=0 %then %do ;
		%SasInput ;
		%StateTranslate1 ;
	%end ;
	%else %if &statecodetype=1 %then %do ;
		%SasInput ;
		%StateTranslate2 ;
	%end ;
%end ;
%else %if &inputformat = 2 %then %do ;
	%if &statecodetype=0 %then %do ;
		%SasInput2 ;
		%StateTranslate1 ;
	%end ;
	%else %if &statecodetype=1 %then %do ;
		%SasInput2 ;
		%StateTranslate2 ;
	%end ;
%end ;
/**************************************************************************************/





/**************************************************************************************
***************************************************************************************
***************************************************************************************
***************************************************************************************
***************************************************************************************
*****																			  *****
*****                       B. BRACKETREADER MACRO                                *****
*****																			  *****
***************************************************************************************
***************************************************************************************
***************************************************************************************
***************************************************************************************
***************************************************************************************
*   This is a macro that runs taxable income through the bracket and rate structure.  *
*   When the macro is invoked in other parts of the program, it generates the text    *
*   necessary to calculate tax liability from taxable income in that part of the      *
*   program. Local names of the applicable variables are substituted for the macro    *
*   variables (the macro variables are the names beginning with "M"). Note that the   *
*   arrays are all defined in step (8), the data step.                                *
*                                                                                     *
*   Bracketreader macro variable names and their meaning:                             *
*   Mti = taxable income                                                              *
*   Mtax = tax liability                                                              *
*   Mrate = rate array                                                                *
*   Mbracket = bracket array                                                          *
*   Mbracknum = number of brackets                                                    *
***************************************************************************************/

%macro bracketreader(Mti, Mtax, Mrate, Mbracket, Mbracknum) ;

&Mtax = 0;
found=0;
i=0;
j=0;

if &Mti = 0 then do;
        Brackmtr = 0;
        &Mtax = 0;
end;

else do;
        do until (found=1);
                i=i+1;
                j=i+1;
                if i >= &Mbracknum then do;
                        &Mtax = &Mtax + ( &Mrate.{i} /100) * max(( &Mti - &Mbracket.{i}),0);
                        Brackmtr = &Mrate.{i};
                        found=1;
                end;
                else if &Mti < &Mbracket.{j} then do;
                        &Mtax = &Mtax + ( &Mrate.{i} /100)*max(( &Mti - &Mbracket.{i} ),0);
                        Brackmtr = &Mrate.{i};
                        found=1;
                end;
                else do;
                        &Mtax = &Mtax
                                + ( &Mrate.{i} /100)*( &Mbracket.{j} - &Mbracket.{i} );
                end;
        end;
end;
%mend bracketreader ;
/*****************************************************************************************/



/****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****																				*****
*****           C. MAKEDATA, ITERATION1, MTRCALC, AND CLOSEDATASTEP MACROS          *****
*****		   																		*****
*****																				*****
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
This section of the program goes through several iterations of the federal and state tax
calculation macros, in order to deal with deductibility of one tax from another
and vice versa, and to calculate marginal tax rates by adding an increment to
income or deductions. See documentation for list of output variables and their meaning.

The data step is divided into macros to make it easier to modify the program for de-bugging,
and to facilitate supressing unnecessary code in order to speed processing. 
*****************************************************************************************/

%macro MakeData ;
 
data taxresults ;
	length taxtype $ 8 ;
	length Ftaxtype $ 8 ;
	set idataset ;

		/* reset statekey=0 in cases with no state tax or no state data */
		if (statename in ("fl","tx","wa")) or
			(statename="ak" and (stateyear<1949 or stateyear>=1979)) or
			(statename="al" and stateyear<1933) or
			(statename="ar" and stateyear<1928) or
			(statename="az" and stateyear<1933) or
			(statename="ca" and stateyear<1935) or
			(statename="co" and stateyear<1937) or
			(statename="ct" and stateyear<1969) or
			(statename="dc" and stateyear<1939) or
			(statename="de" and stateyear<1917) or
			(statename="ga" and stateyear<1929) or
			(statename="hi" and stateyear<1901) or
			(statename="ia" and stateyear<1934) or
			(statename="id" and stateyear<1931) or
			(statename="il" and stateyear<1969) or
			(statename="in" and stateyear<1933) or
			(statename="ks" and stateyear<1933) or
			(statename="ky" and stateyear<1936) or
			(statename="la" and stateyear<1934) or
			(statename="ma" and stateyear<1917) or
			(statename="md" and stateyear<1937) or
			(statename="me" and stateyear<1969) or
			(statename="mi" and stateyear<1967) or
			(statename="mn" and stateyear<1933) or
			(statename="mo" and stateyear<1917) or
			(statename="ms" and stateyear<1912) or
			(statename="mt" and stateyear<1933) or
			(statename="nc" and stateyear<1901) or
			(statename="nd" and stateyear<1919) or
			(statename="ne" and stateyear<1968) or
			(statename="nh" and stateyear<1923) or
			(statename="nj" and stateyear<1975) or
			(statename="nm" and stateyear<1933) or
			(statename="nv" and stateyear<1973) or
			(statename="ny" and stateyear<1919) or
			(statename="oh" and stateyear<1972) or
			(statename="ok" and stateyear<1908) or
			(statename="or" and stateyear<1929) or
			(statename="pa" and stateyear<1971) or
			(statename="ri" and stateyear<1969) or
			(statename="sc" and stateyear<1900 
				or 1918<=stateyear<=1921) or
			(statename="sd" and (stateyear<1933 or 
				(stateyear>1942 and stateyear<1976))) or
			(statename="tn" and stateyear<1929) or
			(statename="ut" and stateyear<1931) or
			(statename="va" and stateyear<1900) or
			(statename="vt" and stateyear<1931) or
			(statename="wi" and stateyear<1911) or
			(statename="wv" and (stateyear<1935 
				or 1941<stateyear<1961)) or
			(statename="wy" and stateyear<1984) or
			soi=0 or stateyear < max( &yearstart , 1900) 
			or stateyear>2007 			
			then do ;
				statekey=0 ;
				taxtype="none" ;
				statekeep=statename ;
				filertypekeep=filertype ;
				stateyearkeep=stateyear ;
				soikeep=soi ;
		end ;

		/* reset fedkey=0 for years with no federal tax or no data */
		if fedyear<1913 then do ;
			fedkey=0 ;
			Ftaxtype="none" ;
			filertypekeep=filertype ;
			fedyearkeep=fedyear ;
		end ;

		/* lookup state and federal tax parameters, merge with taxpayer records */
		set StateLaw key = statekey/unique;
		set FedLaw key = fedkey/unique  ;

		/* if statekey=0 or fedkey=0, restore some overwritten variables */
		if statekey=0 then do ;
			statename=statekeep ;
			filertype=filertypekeep ;
			stateyear=stateyearkeep ;
			soi=soikeep ;
		end ;
		if fedkey=0 then do ;
			filertype=filertypekeep ;
			fedyear=fedyearkeep ;
		end ;

        length incrementkind $ 8 ;
        incrementkind=resolve('&incrementkind');
		income = round(income) ; 		wagsal1 = round(wagsal1) ; 		wagsal2 = round(wagsal2) ;
		businc1 = round(businc1) ;		businc2 = round(businc2) ;		farminc1 = round(farminc1) ;
		farminc2 = round(farminc2) ;	ltcg1 = round(ltcg1) ;			ltcg2 = round(ltcg2) ;
		othcg1 = round(othcg1) ;		othcg2 = round(othcg2) ;		div1 = round(div1) ;
		div2 = round(div2) ;			int1 = round(int1) ;			int2 = round(int2) ;
		teint1 = round(teint1) ;		teint2 = round(teint2) ;		pension1 = round(pension1) ;
		pension2 = round(pension2) ;	rentinc1 = round(rentinc1) ;	rentinc2 = round(rentinc2) ;
		ui1 = round(ui1) ;				ui2 = round(ui2) ;				ssben1 = round(ssben1) ;
		ssben2 = round(ssben2) ;		partscorp1 = round(partscorp1);	partscorp2 = round(partscorp2) ;
		othinc1 = round(othinc1) ;		othinc2 = round(othinc2) ;		othadj1 = round(othadj1) ;
		othadj2 = round(othadj2) ;		charity = round(charity) ;		charcg = round(charcg) ;
		intpaid = round(intpaid) ;		invint = round(invint) ;		stinctax = round(stinctax);
		proptax = round(proptax) ;		salestax = round(salestax) ;	taxnodetail = round(taxnodetail) ;
		medexp = round(medexp) ;		casualty = round(casualty) ;    movex = round(movex) ;
		busex = round(busex) ;			miscdedlim = round(miscdedlim);	omiscded = round(omiscded) ;
		childcare = round(childcare) ;	fdcred = round(fdcred) ;		otaxpref = round(otaxpref) ;
		oamtadj = round(oamtadj) ;		avglaginc = round(avglaginc) ;  psincome = round(psincome) ;
		psded = round(psded) ; 
		if age=0 and agenum=1 then agex=65;
        else agex=age;
        if agesp=0 and agenum=2 and filertype="m" then agespx=65;
        else agespx=agesp;

/* Define arrays for tax brackets and rates */
array Fbracket{55} Fb1-Fb55 ;
array Frate{55} Fr1-Fr55 ;
array Fxbracket{3} Fxb1-Fxb3 ;
array Fxrate{3} Fxr1-Fxr3 ;
array Famtbracket{3} Famtb1-Famtb3 ;
array Famtrate{3} Famtr1-Famtr3 ;
array bracket{26} b1-b26 ;
array rate{26} r1-r26 ;
array xbracket{14} xb1-xb14 ;
array xrate{14} xr1-xr14 ;

/**********************************************************************************
* Modify brackets for states where exemptions are deducted against lowest bracket *
***********************************************************************************/
if taxtype ne "none" then do ;
	if exlim=2 then do ;
		exempt=expercap*(1 + (Filertype="m") + deps)
    	+ exreturn + (ex_dep * deps) + (ex_age * agenum) ;

		b2 = b2 + exempt ;
		if b2>b3 then b3=b2 ;
		if b3>b4 then b4=b3 ;
	end ;
end ;

/************************************
* Income calculations               *
*************************************/

/* gross positive self-employment income */
seinc1 = max(0,businc1+farminc1) ;
seinc2 = max(0,businc2+farminc2) ;
seinc = seinc1 + seinc2 ;

/* positive labor income        */
labinc1 = max(wagsal1 + businc1 + farminc1, 0) ;
labinc2 = max(wagsal2 + businc2 + farminc2, 0) ;
labinc = max(wagsal1+wagsal2+businc1+businc2+farminc1+farminc2, 0) ;

/* non-farm positive labor income */
nflabinc1 = max(wagsal1 + businc1, 0) ;
nflabinc2 = max(wagsal2 + businc2, 0) ;
nflabinc = max(wagsal1 + wagsal2 + businc1 + businc2, 0) ;

/* labor income */
lab1=wagsal1+businc1+farminc1 ;
lab2=wagsal2+businc2+farminc2 ;
lab=lab1+lab2 ;

/* combine other elements of income */

wagsal = wagsal1 + wagsal2 ;
businc = businc1 + businc2 ;
farminc = farminc1 + farminc2 ;
ltcg = ltcg1 + ltcg2 ;
othcg = othcg1 + othcg2 ;
div = div1 + div2 ;
int = int1 + int2 ;
teint = teint1 + teint2 ;
pension = pension1 + pension2 ;
rentinc = rentinc1 + rentinc2 ;
ui = ui1 + ui2 ;
ssben = ssben1 + ssben2 ;
partscorp = partscorp1 + partscorp2 ;
othinc = othinc1 + othinc2 ;
othadj = othadj1 + othadj2 ;

/* allocate business expenses and moving expenses between spouses */
if (labinc1+labinc2)>0 then do ;
	busex1 = busex*(labinc1/(labinc1+labinc2)) ;
	busex2 = busex*(labinc2/(labinc1+labinc2)) ;
	movex1 = movex*(labinc1/(labinc1+labinc2)) ;
	movex2 = movex*(labinc2/(labinc1+labinc2)) ;
end ;
else do ; 
	busex1 = busex/2 ;
	busex2 = busex/2 ;
	movex1 = movex/2 ;
	movex2 = movex/2 ;
end ;

/* Define increment for calculating marginal tax rates */
length mtrvar $ 16 ;
mtrvar=resolve('&mtrvar');
if incrementkind="dollar" then increment = &incrementquantity ;
else if incrementkind="incpct" then
        increment = max(0.10,( &incrementquantity /100)*income) ;

/* Set starting values of certain variables to zero */
iteration=0 ;
taxf=0; taxf1=0; taxf2=0; taxfns=0; taxs=0; taxs1=0; taxs2=0; FmtrNORM=0; FmtrNORM2=0;
SmtrNORM=0; SmtrNORM2=0; Fagi=0; Fagi1=0 ; Fagi2=0 ; Fssagi=0; 
Fti=0; Fti1=0; Fti2=0; Fexempt=0; Fstded=0; Fitemded=0; Fitemizer=0; Fitemlost=0; 
Fidmaxlim=0; FtaxNORM=0; FtaxMAXEI=0; FtaxALTCG=0; FtaxINCAVG=0; FmtrMEI=0; 
Fdtxliab_bc=0; FtaxMIN=0; Famt=0; Famtpref=0; Famti=0; 
Famtexempt=0; Famtiae=0; FamtiaeEXCG=0; Ftamt=0; FtiSI=0; FtaxSI=0; FmtrNORMSI=0;
FtaxALTCGSI=0; FtaxEXCGSI=0; FamtSI=0; FamtexemptSI=0; FamtiaeSI=0; FamtiaeEXCGSI=0;
FtamtSI=0; FamtSI=0; Fkcarecred=0 ; Fkcareded=0 ; Feic=0; Fkidcred=0; Fkidcredref=0;
Fsstxliab=0 ; agi=0; agi1=0; agi2=0; Sti=0; Sti1=0; Sti2=0; exempt=0 ; exempt1=0 ;
exempt2=0 ; stded=0 ; itemded=0 ; itemded1=0 ; itemded2=0 ; itemizer_s=0 ; retexamt=0; 
lowexamt=0; miscex=0; StaxNORM=0; sptxliab=0; sptx2liab=0; StaxALTCG=0; StaxASP=0; 
StaxAMIN=0; StaxMIN=0; StaxMIN1=0; StaxMIN2=0; StaxTAMT=0; gencred=0; retcred=0; 
retcredref=0; lowcred=0; lowcredref=0; marcred=0 ; kcarecred=0 ; StaxAGC=0; xtaxs=0; 
xtaxs1=0; xtaxs2=0; xcredit=0; StaxAX=0; eicstateref=0 ; eicstatenoref=0 ; Fsepfiler=0 ; 
Ssepfiler=0 ; Fidsharekept=0 ; propcred=0; iteration=1 ; FtaxNORM1=0 ; FtaxNORM2=0 ;
FtaxALTCG1=0 ; FtaxALTCG2=0 ; Fexempt1=0 ; Fexempt2=0 ; Fuiagi=0 ; Fssagi=0 ; Fsstxliab1=0 ;
Fsstxliab2=0 ; FsstxliabSE1=0 ; FsstxliabSE2=0 ; Fdtxliab_bc1=0 ; Fdtxliab_bc2=0 ;
iunprotected=0 ; Fexltcg=0 ; Ftaxpref=0 ; Famtpref=0 ; Fidsharekept=0 ; tax_nonincome=0 ;
Feldcred=0 ; FtiEXCG=0 ; FtaxEXCG=0 ; FxtiEXCG=0 ; FxtaxEXCG=0 ; FoldEIcredit=0 ;
Fxtax=0 ; Fxti=0 ; dedfit=0 ; taxpref1=0 ; taxpref2=0 ; amtpref1=0 ; amtpref2=0 ;
FtaxprefSI=0 ; FtaxMINSI=0 ; deductcycle=0 ; 
localtax=0 ;
FtiNI=0 ; FtiYI=0 ; FtaxNORMNI=0 ; FtaxNORMYI=0 ;
FtamtEXCG=0 ; CGa=0 ; CGaX=0 ; CGb=0 ; CGbX=0 ;
FtamtALTCG=0 ; FtaxCGaX=0 ; FtaxCGbX=0 ;
FtamtEXCGSI=0 ; CGaSI=0 ; CGaXSI=0 ; CGbSI=0 ; CGbXSI=0 ;
FtamtALTCGSI=0 ; FtaxCGaXSI=0 ; FtaxCGbXSI=0 ;
FitemizerSI=0 ; FtaxprefSI=0 ; FamtprefSI=0 ;
FdivcredSI=0 ;
taxs_S=0 ; taxs1_S=0 ; taxs2_S=0 ; taxsFSI=0 ;
itemded_S=0 ; itemded1_S=0 ; itemded2_S=0 ;
xitemizer_s=0 ; taxsFNI=0 ; taxsFYI=0 ;
FitemizerSI=0 ; taxfSI=0 ; FamtSI=0 ;
Fdtxliab_bcSI=0 ; FtamtSI=0 ; FamtiSI=0 ;
FamtiaeSI=0 ; FtiSI=0 ;	FtaxNORMSI=0 ;
FmtrNORMSI=0 ; FmtrNORMSI=0 ; FamtprefSI=0 ;
FtaxALTCGSI=0 ; FtaxMAXEISI=0 ; FtaxINCAVGSI=0 ; 
FmtrMEISI=0 ; FtaxMINSI=0 ; FtaxprefSI=0 ;	
FamtexemptSI=0 ; FamtiaeEXCGSI=0 ; FtamtEXCGSI=0 ;
CGaSI=0 ; CGaXSI=0 ; CGbSI=0 ; 
CGbXSI=0 ; FtamtALTCGSI=0 ; FtaxCGaXSI=0 ; 
FtaxCGbXSI=0 ; FkidcredSI=0 ; FkidcredrefSI=0 ;
FdivcredSI=0 ; taxsFDED_1=0 ; taxsFDED_2=0 ; taxsFDED_3=0 ;
FitemizerA=0 ; FitemizerB=0 ; FitemizerC=0 ; FitemizerD=0 ; 
FitemizerE=0 ; FitemizerF=0 ;
itemizer_sA=0 ; itemizer_sB=0 ; itemizer_sC=0 ; 
itemizer_sD=0 ; itemizer_sE=0 ; itemizer_sF=0 ;
xitemizer_sA=0 ; xitemizer_sB=0 ; xitemizer_sC=0 ; 
xitemizer_sD=0 ; xitemizer_sE=0 ; xitemizer_sF=0 ;
itemizerSEPA=0 ; itemizerSEPB=0 ; itemizerSEPC=0 ; 
itemizerSEPD=0 ; itemizerSEPE=0 ; itemizerSEPF=0 ;
SMINitemizerA=0 ; SMINitemizerB=0 ; SMINitemizerC=0 ; 
SMINitemizerD=0 ; SMINitemizerE=0 ; SMINitemizerF=0 ;
SMINitemizerSEPA=0 ; SMINitemizerSEPB=0 ; SMINitemizerSEPC=0 ; 
SMINitemizerSEPD=0 ; SMINitemizerSEPE=0 ; SMINitemizerSEPF=0 ;
SMINitemizer=0 ; SMINitemizerSEP=0 ;
itemizer_sCONSTANT=0 ; itemizerSEPCONSTANT=0 ; xitemizer_sCONSTANT=0 ; 
SMINitemizerCONSTANT=0 ; SMINitemizerSEPCONSTANT=0 ;
itemizer_sFSIA=0 ; itemizerSEPFSIA=0 ; xitemizer_sFSIA=0 ; 
SMINitemizerFSIA=0 ; SMINitemizerSEPFSIA=0 ;
itemizer_sFSIB=0 ; itemizerSEPFSIB=0 ; xitemizer_sFSIB=0 ; 
SMINitemizerFSIB=0 ; SMINitemizerSEPFSIB=0 ;
itemizer_sFSIC=0 ; itemizerSEPFSIC=0 ; xitemizer_sFSIC=0 ; 
SMINitemizerFSIC=0 ; SMINitemizerSEPFSIC=0 ;
itemizer_sFSID=0 ; itemizerSEPFSID=0 ; xitemizer_sFSID=0 ; 
SMINitemizerFSID=0 ; SMINitemizerSEPFSID=0 ;
itemizer_sFSIE=0 ; itemizerSEPFSIE=0 ; xitemizer_sFSIE=0 ; 
SMINitemizerFSIE=0 ; SMINitemizerSEPFSIE=0 ;
itemizer_sFSIF=0 ; itemizerSEPFSIF=0 ; xitemizer_sFSIF=0 ; 
SMINitemizerFSIF=0 ; SMINitemizerSEPFSIF=0 ;
tax_nonincomeA=0 ; tax_nonincomeB=0 ; tax_nonincomeC=0 ; 
tax_nonincomeD=0 ; tax_nonincome_S=0 ;
Fkidcred_S=0 ; Fkidcredref_S=0 ;
Fchlimbind=0 ; chlimbind=0 ; xagi=0 ;
FtiEXCGSI=0 ;
/********/

%mend MakeData ; 

%macro Iteration1 ;
/***********************************************
*  Invoke macros to calculate taxes            *
************************************************/
/*	_1 indicates "before adding MTR increment" *	
*   _2 indicates "after adding MTR increment"  *
*   _3 indicates "after adding MTR increment"  *
************************************************/
 
/*** ITERATION ONE -- BEFORE ADDING INCREMENT FOR MTR ***/

/*** If there is a federal income tax ***/
if Ftaxtype="fedinc" then do;
        taxs=0; taxs1=0 ; taxs2=0 ; Ssepfiler=0; itemded=0; itemded1=0; itemded2=0;
		deductcycle=0 ;
		Fitemizer=0 ; itemizer_s=0 ; taxfSI=0 ; taxs_S=0 ; taxs1_S=0 ; taxs2_S=0 ; 
		itemded_S=0 ; itemded1_S=0 ; itemded2_S=0 ; taxsFNI=0 ; taxsFYI=0 ;
		
		lastcalc="none" ;
		/* Restore lines below to save all variables from all iterations
		if &detail = 2 then file resultsf(allvars01.txt) lrecl=25000 ;
		if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
		Restore lines above to save all variables from all iterations */

        %fedtax ;
        taxfns=taxf;
		FitemizerA=Fitemizer ;
		
		lastcalc = "federal" ;
		/* Restore lines below to save all variables from all iterations
		if &detail = 2 then file resultsf(allvars02.txt) lrecl=25000 ;
		if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
		Restore lines above to save all variables from all iterations */

		deductcycle=1 ;


        /*** If there is NOT a state income tax, then skips to end of section ***/

        /*** If there IS a state income tax ***/
        if taxtype ne "none" then do;

                 /* 1st state tax calculation, then 2nd federal to capture
                deduction for state income tax at federal level*/
                %statetax ;
				itemizer_sA = itemizer_s ;
				xitemizer_sA = xitemizer_s ;
				itemizerSEPA = itemizerSEP ;
				SMINitemizerA = SMINitemizer ;
				SMINitemizerSEPA = SMINitemizerSEP ;
				
				lastcalc = "state" ;
				/* Restore lines below to save all variables from all iterations
				if &detail = 2 then file resultsf(allvars03.txt) lrecl=25000 ;
				if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
				Restore lines above to save all variables from all iterations */


                %fedtax ;
				FitemizerB = Fitemizer ;
				
				lastcalc = "federal" ;
				/* Restore lines below to save all variables from all iterations
				if &detail = 2 then file resultsf(allvars04.txt) lrecl=25000 ;
				if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
				Restore lines above to save all variables from all iterations */

				deductcycle=2 ;

                /* If either federal or state tax is deductible at state level, or there is a state AMT based on
				federal, or there is a constraint on state itemization status, or if there is a state limitation
				on itemized deductions that depends on the federal calculation of same, or taxnodetail>0, each tax is 
				computed iteratively a total of 4 times */
                if dedfed=1 or xdedfed=1 or sitded=1 or xsitded=1 or taxtype="pctfed" 
					or taxtype="pctfed3" or taxtype="pctfed4" or mintaxtype>0 or itemiz>1 
					or (itemlim>0 and Fidmaxlim=1) or taxnodetail>0 then do;
                        %statetax ;

						itemizer_sB = itemizer_s ;
						xitemizer_sB = xitemizer_s ;
						itemizerSEPB = itemizerSEP ;
						SMINitemizerB = SMINitemizer ;
						SMINitemizerSEPB = SMINitemizerSEP ;
						
						lastcalc = "state" ;
						/* Restore lines below to save all variables from all iterations
						if &detail = 2 then file resultsf(allvars05.txt) lrecl=25000 ;
						if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
						Restore lines above to save all variables from all iterations */

                        %fedtax ;

						FitemizerC = Fitemizer ;
						
						lastcalc = "federal" ;
						/* Restore lines below to save all variables from all iterations
						if &detail = 2 then file resultsf(allvars06.txt) lrecl=25000 ;
						if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
						Restore lines above to save all variables from all iterations */

						deductcycle=3 ;
                        %statetax ;

						itemizer_sC = itemizer_s ;
						xitemizer_sC = xitemizer_s ;
						itemizerSEPC = itemizerSEP ;
						SMINitemizerC = SMINitemizer ;
						SMINitemizerSEPC = SMINitemizerSEP ;
						
						lastcalc = "state" ;
						/* Restore lines below to save all variables from all iterations
						if &detail = 2 then file resultsf(allvars07.txt) lrecl=25000 ;
						if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
						Restore lines above to save all variables from all iterations */

						%fedtax ;

						FitemizerD = Fitemizer ;

						
						lastcalc = "federal" ;
						/* Restore lines below to save all variables from all iterations
						if &detail = 2 then file resultsf(allvars08.txt) lrecl=25000 ;
						if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
						Restore lines above to save all variables from all iterations */

						deductcycle=4 ;
						taxsFDED_1=taxsFYI ;
						%statetax ;

						itemizer_sD = itemizer_s ;
						xitemizer_sD = xitemizer_s ;
						itemizerSEPD = itemizerSEP ;
						SMINitemizerD = SMINitemizer ;
						SMINitemizerSEPD = SMINitemizerSEP ;
						
						lastcalc = "state" ;
						/* Restore lines below to save all variables from all iterations
						if &detail = 2 then file resultsf(allvars09.txt) lrecl=25000 ;
						if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
						Restore lines above to save all variables from all iterations */

						/* Add two extra iterations if taxnodetail>0 */
						if taxnodetail>0 then do ;

							%fedtax ;

							FitemizerE = Fitemizer ;
						
							lastcalc = "federal" ;
							/* Restore lines below to save all variables from all iterations
							if &detail = 2 then file resultsf(allvars10.txt) lrecl=25000 ;
							if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
							Restore lines above to save all variables from all iterations */

							deductcycle=5 ;
							%statetax ;

							itemizer_sE = itemizer_s ;
							xitemizer_sE = xitemizer_s ;
							itemizerSEPE = itemizerSEP ;
							SMINitemizerE = SMINitemizer ;
							SMINitemizerSEPE = SMINitemizerSEP ;
						
							lastcalc = "state" ;
							/* Restore lines below to save all variables from all iterations
								if &detail = 2 then file resultsf(allvars11.txt) lrecl=25000 ;
							if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
							Restore lines above to save all variables from all iterations */

							%fedtax ;

							FitemizerF = Fitemizer ;
						
							lastcalc = "federal" ;
							/* Restore lines below to save all variables from all iterations
							if &detail = 2 then file resultsf(allvars10.txt) lrecl=25000 ;
							if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
							Restore lines above to save all variables from all iterations */

							deductcycle=6 ;
							taxsFDED_1=taxsFYI ;
							%statetax ;

							itemizer_sF = itemizer_s ;
							xitemizer_sF = xitemizer_s ;
							itemizerSEPF = itemizerSEP ;
							SMINitemizerF = SMINitemizer ;
							SMINitemizerSEPF = SMINitemizerSEP ;
						
							lastcalc = "state" ;
							/* Restore lines below to save all variables from all iterations
								if &detail = 2 then file resultsf(allvars11.txt) lrecl=25000 ;
							if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
							Restore lines above to save all variables from all iterations */

						end ;
                end;
				else taxsFDED_1=taxsFYI ;
        end;
		else taxFDED_1=0 ;
end;

/* If there is no federal tax but there is a state tax */
else if (Ftaxtype="none") then if (taxtype ne "none") then do ;
        %statetax ;
		taxsFDED_1=taxsFYI ;
end;

/* Rename key variables from first iteration to preserve them */
taxf_1=taxf; taxfns_1=taxfns; taxs_1=taxs; taxs1_1=taxs1;
taxs2_1=taxs2; FmtrNORM_1=FmtrNORM/100; FmtrNORM2_1=FmtrNORM2/100;
SmtrNORM_1=SmtrNORM/100; SmtrNORM2_1=SmtrNORM2/100; Fsstxliab_1=Fsstxliab; 

%mend Iteration1 ;

%macro Detail1 ;
Fagi_1=Fagi; Fssagi_1=Fssagi; Fti_1=Fti; Fti1_1=Fti1; Fti2_1=Fti2; Fexempt_1=Fexempt; 
Fstded_1=Fstded; Fitemded_1=Fitemded; Fitemizer_1=Fitemizer; Fitemlost_1=Fitemlost;
Fidmaxlim_1=Fidmaxlim; FtaxNORM_1=FtaxNORM; FtaxMAXEI_1=FtaxMAXEI; FtaxALTCG_1=FtaxALTCG;
FtaxINCAVG_1=FtaxINCAVG; FmtrMEI_1=FmtrMEI; Fdtxliab_bc_1=Fdtxliab_bc; FtaxMIN_1=FtaxMIN;
Famt_1=Famt; Famtpref_1=Famtpref; Famti_1=Famti; Famtexempt_1=Famtexempt; 
Famtiae_1=Famtiae; FamtiaeEXCG_1=FamtiaeEXCG; Ftamt_1=Ftamt; Fkcarecred_1 = Fkcarecred ;
Feic_1=Feic; Fkidcred_1=Fkidcred; Fkidcredref_1=Fkidcredref; Feldcred_1=Feldcred ;
agi_1=agi; agi1_1=agi1; agi2_1=agi2; Sti_1=Sti; Sti1_1=Sti1; Sti2_1=Sti2;
exempt_1=exempt ; exempt1_1=exempt1 ; exempt2_1=exempt2 ; stded_1=stded ;
itemded_1=itemded ; itemded1_1=itemded1 ; itemded2_1=itemded2 ; itemizer_s_1=itemizer_s ;
retexamt_1=retexamt; lowexamt_1=lowexamt; miscex_1=miscex; StaxNORM_1=StaxNORM;
sptxliab_1=sptxliab; sptx2liab_1=sptx2liab; StaxALTCG_1=StaxALTCG; StaxASP_1=StaxASP;
StaxAMIN_1=StaxAMIN; StaxMIN_1=StaxMIN; gencred_1=gencred; retcred_1=retcred;
retcredref_1=retcredref; lowcred_1=lowcred; lowcredref_1=lowcredref; marcred_1=marcred;
kcarecred_1=kcarecred ; StaxAGC_1=StaxAGC; xtaxs_1=xtaxs; xcredit_1=xcredit;
StaxAX_1=StaxAX; eicstateref_1=eicstateref ; eicstatenoref_1=eicstatenoref ;
Fsepfiler_1=Fsepfiler ; Ssepfiler_1=Ssepfiler ; propcred_1=propcred ;
FtiEXCG_1=FtiEXCG ; FtaxEXCG_1=FtaxEXCG ; FxtiEXCG_1=FxtiEXCG ; 
FxtaxEXCG_1=FxtaxEXCG ; FoldEIcredit_1=FoldEIcredit ; Fxtax_1=Fxtax ; Fxti_1=Fxti ;
dedfit_1=dedfit ; FsstxliabSE1_1=FsstxliabSE1 ; FsstxliabSE2_1=FsstxliabSE2 ;
localtax_1=localtax ; Fchlimbind_1 = Fchlimbind ; chlimbind_1 = chlimbind ;
%mend ;

/* MTRCALC MACRO -- PERFORMS ADDITIONAL ITERATIONS FOR CALCULATING MARGINAL RATES */
%macro MTRcalc ;
  %macro Iteration2 ;

  /*** ITERATION TWO -- AFTER ADDING INCREMENT FOR MTR ***/

  /* Add increment for calculating MTR */
	iteration=2 ;
	&mtrvar = &mtrvar + increment;
	if mtrvar in ("wagsal1","wagsal2","businc1","businc2","farminc1","farminc2",
		"ltcg1","ltcg2","othcg1","othcg2","div1","div2","int1","int2","teint1",
		"teint2","pension1","pension2","rentinc1","rentinc2","ui1","ui2","ssben1", 
		"ssben2","partscorp1","partscorp2","othinc1","othinc2","psincome") 
		then income = income + increment ;
	if mtrvar in ("wagsal1","wagsal2","businc1","businc2","psincome") and psincome ne -1 then do ;
		psincome = psincome + increment ;
	end ;
	if (fedyear=1981 and oamtadj > 0) then oamtadj = oamtadj + increment ;

  /************************************
  * Re-do income calculations         *
  *************************************/

  /* gross positive self-employment income */
  seinc1 = max(0,businc1+farminc1) ;
  seinc2 = max(0,businc2+farminc2) ;
  seinc = seinc1 + seinc2 ;

  /* positive labor income        */
  labinc1 = max(wagsal1 + businc1 + farminc1, 0) ;
  labinc2 = max(wagsal2 + businc2 + farminc2, 0) ;
  labinc = max(wagsal1+wagsal2+businc1+businc2+farminc1+farminc2, 0) ;

  /* non-farm positive labor income */
  nflabinc1 = max(wagsal1 + businc1, 0) ;
  nflabinc2 = max(wagsal2 + businc2, 0) ;
  nflabinc = max(wagsal1 + wagsal2 + businc1 + businc2, 0) ;

  /* labor income */
  lab1=wagsal1+businc1+farminc1 ;
  lab2=wagsal2+businc2+farminc2 ;
  lab=lab1+lab2 ;

  /* combine other elements of income */

  wagsal = wagsal1 + wagsal2 ;
  businc = businc1 + businc2 ;
  farminc = farminc1 + farminc2 ;
  ltcg = ltcg1 + ltcg2 ;
  othcg = othcg1 + othcg2 ;
  div = div1 + div2 ;
  int = int1 + int2 ;
  teint = teint1 + teint2 ;
  pension = pension1 + pension2 ;
  rentinc = rentinc1 + rentinc2 ;
  ui = ui1 + ui2 ;
  ssben = ssben1 + ssben2 ;
  partscrop = partscorp1 + partscorp2 ;
  othinc = othinc1 + othinc2 ;
  othadj = othadj1 + othadj2 ;

  /*** If there is a federal income tax ***/
  if Ftaxtype = "fedinc" then do;
        taxs=0; taxs1=0; taxs2=0; Ssepfiler=0; itemded=0; itemded1=0; itemded2=0;
		deductcycle=0 ;
		Fitemizer=0 ; itemizer_s=0 ; taxfSI=0 ; taxs_S=0 ; taxs1_S=0 ; taxs2_S=0 ; 
		itemded_S=0 ; itemded1_S=0 ; itemded2_S=0 ; taxsFNI=0 ; taxsFYI=0 ;
		 
		lastcalc = "none" ;
		/* Restore lines below to save all variables from all iterations
		if &detail = 2 then file resultsf(allvars11.txt) lrecl=25000 ;
		if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
		Restore lines above to save all variables from all iterations */

        %fedtax ;
        taxfns=taxf;
		
		lastcalc = "federal" ;
		/* Restore lines below to save all variables from all iterations
		if &detail = 2 then file resultsf(allvars12.txt) lrecl=25000 ;
		if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
		Restore lines above to save all variables from all iterations */

		deductcycle=1 ;

        /*** If there is NOT a state income tax, then skips to end of section ***/

        /*** If there IS a state income tax ***/
        if taxtype ne "none" then do;

                /* 1st state tax calculation, then 2nd federal to capture
                deduction for state income tax at federal level*/
                %statetax ;

				
				lastcalc = "state" ;
				/* Restore lines below to save all variables from all iterations
				if &detail = 2 then file resultsf(allvars13.txt) lrecl=25000 ;
				if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
				Restore lines above to save all variables from all iterations */

                %fedtax ;

				
				lastcalc = "federal" ;
				/* Restore lines below to save all variables from all iterations
				if &detail = 2 then file resultsf(allvars14.txt) lrecl=25000 ;
				if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
				Restore lines above to save all variables from all iterations */

				deductcycle=2 ;

                /* If either federal or state tax is deductible at state level, or there is a state AMT based on
				federal, or there is a constraint on state itemization status, or if there is a state limitation
				on itemized deductions that depends on the federal calculation of same, or taxnodetail>0, each tax is 
				computed iteratively a total of 4 times */
                if dedfed=1 or xdedfed=1 or sitded=1 or xsitded=1 or taxtype="pctfed" 
					or taxtype="pctfed3" or taxtype="pctfed4" or mintaxtype>0 or 
					itemiz>1 or (itemlim>0 and Fidmaxlim=1) or taxnodetail>0 then do;
                        %statetax ;

						
						lastcalc = "state" ;
						/* Restore lines below to save all variables from all iterations
						if &detail = 2 then file resultsf(allvars15.txt) lrecl=25000 ;
						if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
						Restore lines above to save all variables from all iterations */

                        %fedtax ;

						
						lastcalc = "federal" ;
						/* Restore lines below to save all variables from all iterations
						if &detail = 2 then file resultsf(allvars16.txt) lrecl=25000 ;
						if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
						Restore lines above to save all variables from all iterations */

						deductcycle=3 ;

                        %statetax ;

						
						lastcalc = "state" ;
						/* Restore lines below to save all variables from all iterations
						if &detail = 2 then file resultsf(allvars17.txt) lrecl=25000 ;
						if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
						Restore lines above to save all variables from all iterations */

						%fedtax ;

						
						lastcalc = "federal" ;
						/* Restore lines below to save all variables from all iterations
						if &detail = 2 then file resultsf(allvars18.txt) lrecl=25000 ;
						if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
						Restore lines above to save all variables from all iterations */

						deductcycle=4 ;
						taxsFDED_2=taxsFYI ;

						%statetax ;

						
						lastcalc = "state" ;
						/* Restore lines below to save all variables from all iterations
						if &detail = 2 then file resultsf(allvars19.txt) lrecl=25000 ;
						if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
						Restore lines above to save all variables from all iterations */

						/* Extra iteration if taxnodetail>0 */
						if taxnodetail>0 then do ;

							%fedtax ;
					
							lastcalc = "federal" ;
							/* Restore lines below to save all variables from all iterations
							if &detail = 2 then file resultsf(allvars20.txt) lrecl=25000 ;
							if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
							Restore lines above to save all variables from all iterations */

							deductcycle=5 ;

							%statetax ;
						
							lastcalc = "state" ;
							/* Restore lines below to save all variables from all iterations
							if &detail = 2 then file resultsf(allvars21.txt) lrecl=25000 ;
							if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
							Restore lines above to save all variables from all iterations */

							%fedtax ;
					
							lastcalc = "federal" ;
							/* Restore lines below to save all variables from all iterations
							if &detail = 2 then file resultsf(allvars20.txt) lrecl=25000 ;
							if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
							Restore lines above to save all variables from all iterations */

							deductcycle=6 ;
							taxsFDED_2=taxsFYI ;

							%statetax ;
						
							lastcalc = "state" ;
							/* Restore lines below to save all variables from all iterations
							if &detail = 2 then file resultsf(allvars21.txt) lrecl=25000 ;
							if &detail = 2 then put iteration= deductcycle= lastcalc= _all_ ;
							Restore lines above to save all variables from all iterations */

						end ;
                end;
				else taxsFDED_2 = taxsFYI ;
        end;
		else taxsFDED_2 = 0 ;
  end;

  /* If there is no federal tax but there is a state tax */
  else if (Ftaxtype="none") then if (taxtype ne "none") then do ;
        %statetax ;
		taxsFDED_2=taxsFYI ;
  end;

  /* Rename key variables from second iteration to preserve them */
  taxf_2 =taxf; taxfns_2 =taxfns; taxs_2 =taxs; taxs1_2 =taxs1; taxs2_2 =taxs2;
  Fsstxliab_2 =Fsstxliab ;

  /* Restore income and deductions to their initial values */
	&mtrvar = &mtrvar - increment ;
	if mtrvar in ("wagsal1" ,"wagsal2" ,"businc1"
		,"businc2" ,"farminc1" ,"farminc2"
		,"ltcg1" ,"ltcg2" ,"othcg1" 
		,"othcg2" ,"div1" ,"div2" ,"int1"
		,"int2" ,"teint1" ,"teint2" 
		,"pension1" ,"pension2" ,"rentinc1" 
		,"rentinc2" ,"ui1" ,"ui2" ,"ssben1" 
		,"ssben2" ,"partscorp1" ,"partscorp2" 
		,"othinc1" ,"othinc2","psincome") then income = income - increment ;
	if mtrvar in ("wagsal1","wagsal2","businc1","businc2","psincome") and psincome ne -1 then do ;
		psincome = psincome - increment ;
	end ;


  /* Calculate marginal tax rates  */
  /* Note that rates for deductions and income are both reported as positive */

  if mtrvar in ("charity" ,"intpaid" ,"invint" ,"stinctax"
	,"proptax" ,"salestax" ,"taxnodetail" 
	,"medexp" ,"casualty" ,"movex" ,"busex"
	,"miscdedlim" ,"omiscded" ,"childcare") then do ;
        mtrfns =max(0,(taxfns_1-taxfns_2)/increment);
        mtrf =(taxf_1-taxf_2)/increment;
        mtrs =(taxs_1-taxs_2)/increment;
        mtr =max(0,mtrf + mtrs );
        mtrsi =mtr - mtrfns ;
		ssmtr =0;
		absmtr = abs(mtr) ;
		absmtrfns = abs(mtrfns) ;
  end;
  else do;
        mtrfns =(taxfns_2-taxfns_1)/increment;
        mtrf =(taxf_2-taxf_1)/increment;
        mtrs =(taxs_2-taxs_1)/increment;
        mtr = mtrf + mtrs ;
        mtrsi = mtr - mtrfns ;
		ssmtr =(Fsstxliab_2-Fsstxliab_1)/increment ;
		absmtr = abs(mtr) ;
		absmtrfns = abs(mtrfns) ;
  end;

  %mend Iteration2 ;

  %macro detail2 ;
  FmtrNORM_2 =FmtrNORM/100; FmtrNORM2_2 =FmtrNORM2/100; 
  SmtrNORM_2 =SmtrNORM/100; SmtrNORM2_2 =SmtrNORM2/100; Fagi_2 =Fagi; 
  Fssagi_2 =Fssagi; Fti_2 =Fti; Fti1_2 =Fti1; Fti2_2 =Fti2; 
  Fexempt_2 =Fexempt; Fstded_2 =Fstded; Fitemded_2 =Fitemded; 
  Fitemizer_2 =Fitemizer; Fitemlost_2 =Fitemlost; Fidmaxlim_2 =Fidmaxlim;
  FtaxNORM_2 =FtaxNORM; FtaxMAXEI_2 =FtaxMAXEI; FtaxALTCG_2 =FtaxALTCG; 
  FtaxINCAVG_2 =FtaxINCAVG; FmtrMEI_2 =FmtrMEI; Fdtxliab_bc_2 =Fdtxliab_bc;
  FtaxMIN_2 =FtaxMIN; Famt_2 =Famt; Famtpref_2 =Famtpref; Famti_2 =Famti;
  Famtexempt_2 =Famtexempt; Famtiae_2 =Famtiae; FamtiaeEXCG_2 =FamtiaeEXCG;
  Ftamt_2 =Ftamt; Fkcarecred_2 = Fkcarecred ; Feic_2 =Feic; Fkidcred_2 =Fkidcred;
  Fkidcredref_2 =Fkidcredref; Feldcred_2 =Feldcred ; agi_2 =agi; agi1_2 =agi1;
  agi2_2 =agi2; Sti_2 =Sti; Sti1_2 =Sti1 ; Sti2_2 =Sti2 ; exempt_2 =exempt ;
  exempt1_2 =exempt1 ; exempt2_2 =exempt2 ; stded_2 =stded ; itemded_2 =itemded ;
  itemded1_2 =itemded1 ; itemded2_2 =itemded2 ; itemizer_s_2 =itemizer_s ;
  retexamt_2 =retexamt; lowexamt_2 =lowexamt; miscex_2 =miscex; StaxNORM_2 =StaxNORM;
  sptxliab_2 =sptxliab; sptx2liab_2 =sptx2liab; StaxALTCG_2 =StaxALTCG;
  StaxASP_2 =StaxASP; StaxAMIN_2 =StaxAMIN; StaxMIN_2 =StaxMIN; gencred_2 =gencred;
  retcred_2 =retcred; retcredref_2 =retcredref; lowcred_2 =lowcred; lowcredref_2 =lowcredref;
  kcarecred_2 =kcarecred; marcred_2 =marcred; StaxAGC_2 =StaxAGC; xtaxs_2 =xtaxs;
  xcredit_2 =xcredit; StaxAX_2 =StaxAX; eicstateref_2 =eicstateref ; 
  eicstatenoref_2 =eicstatenoref ; Fsepfiler_2 =Fsepfiler ; Ssepfiler_2 =Ssepfiler ; 
  propcred_2 =propcred ; FtiEXCG_2 =FtiEXCG ; FtaxEXCG_2 =FtaxEXCG ; FxtiEXCG_2 =FxtiEXCG ; 
  FxtaxEXCG_2 =FxtaxEXCG ; FoldEIcredit_2 =FoldEIcredit ; Fxtax_2 =Fxtax ; Fxti_2 =Fxti ;
  dedfit_2 =dedfit ; FsstxliabSE1_2 =FsstxliabSE1 ; FsstxliabSE2_2 =FsstxliabSE2 ;
  localtax_2 = localtax ; Fchlimbind_2 = Fchlimbind ; chlimbind_2 = chlimbind ;
  %mend detail2 ;

  %macro Iteration3 ;
  /*** ITERATION THREE -- OPTIONAL ALTERNATIVE MARGINAL TAX RATE COMPUTATION ***/
  /* This iteration subtracts the increment instead of adding it. The calculator
  will compare the overall marginal tax rate from the 2nd and 3rd iteration, and
  will report for each observation the results from the iteration with the smaller
  absolute value (or iteration 2 if there is a tie). This only executes if the
  "ReverseMTR parameter in the IncTaxCalc macro is set to 1. */ 
  if absmtr > &checkMTR or absmtrfns > &checkMTR then do ;
	/* Subtract increment for calculating MTR */
	iteration=3 ;
	increment_3 = (-1)*increment ;
	&mtrvar = &mtrvar + increment_3 ;
	taxs=0; taxs1=0; taxs2=0; Ssepfiler=0;
	if mtrvar in ("wagsal1" ,"wagsal2" ,"businc1"
		,"businc2" ,"farminc1" ,"farminc2"
		,"ltcg1" ,"ltcg2" ,"othcg1" 
		,"othcg2" ,"div1" ,"div2" ,"int1"
		,"int2" ,"teint1" ,"teint2" 
		,"pension1" ,"pension2" ,"rentinc1" 
		,"rentinc2" ,"ui1" ,"ui2" ,"ssben1" 
		,"ssben2" ,"partscorp1" ,"partscorp2" 
		,"othinc1" ,"othinc2","psincome") then do ;
		income = income + increment_3 ;
	end ;
	if mtrvar in ("wagsal1","wagsal2","businc1","businc2","psincome") and psincome ne -1 then do ;
		psincome = psincome + increment_3 ;
	end ;
	if (fedyear=1981 and oamtadj > 0) then oamtadj = oamtadj + increment_3 ;

	/************************************
	* Re-do income calculations         *
	*************************************/

	/* gross positive self-employment income */
	seinc1 = max(0,businc1+farminc1) ;
	seinc2 = max(0,businc2+farminc2) ;
	seinc = seinc1 + seinc2 ;

	/* positive labor income        */
	labinc1 = max(wagsal1 + businc1 + farminc1, 0) ;
	labinc2 = max(wagsal2 + businc2 + farminc2, 0) ;
	labinc = max(wagsal1+wagsal2+businc1+businc2+farminc1+farminc2, 0) ;

	/* non-farm positive labor income */
	nflabinc1 = max(wagsal1 + businc1, 0) ;
	nflabinc2 = max(wagsal2 + businc2, 0) ;
	nflabinc = max(wagsal1 + wagsal2 + businc1 + businc2, 0) ;

	/* labor income */
	lab1=wagsal1+businc1+farminc1 ;
	lab2=wagsal2+businc2+farminc2 ;
	lab=lab1+lab2 ;

	/* combine other elements of income */

	wagsal = wagsal1 + wagsal2 ;
	businc = businc1 + businc2 ;
	farminc = farminc1 + farminc2 ;
	ltcg = ltcg1 + ltcg2 ;
	othcg = othcg1 + othcg2 ;
	div = div1 + div2 ;
	int = int1 + int2 ;
	teint = teint1 + teint2 ;
	pension = pension1 + pension2 ;
	rentinc = rentinc1 + rentinc2 ;
	ui = ui1 + ui2 ;
	ssben = ssben1 + ssben2 ;
	partscrop = partscorp1 + partscorp2 ;
	othinc = othinc1 + othinc2 ;
	othadj = othadj1 + othadj2 ;

	/*** If there is a federal income tax ***/
	if Ftaxtype = "fedinc" then do;
        taxs=0; taxs1=0 ; taxs2=0 ; Ssepfiler=0; itemded=0; itemded1=0; itemded2=0;
		deductcycle=0 ;
		Fitemizer=0 ; itemizer_s=0 ; taxfSI=0 ; taxs_S=0 ; taxs1_S=0 ; taxs2_S=0 ; 
		itemded_S=0 ; itemded1_S=0 ; itemded2_S=0 ; taxsFNI=0 ; taxsFYI=0 ;

		lastcalc = "none" ;
		/* Restore lines below to save all variables from all iterations
		if &detail = 2 and iteration = 3 then file resultsf(allvars22.txt) lrecl=25000 ;
		if &detail = 2 and iteration = 3 then put iteration= deductcycle= lastcalc= _all_ ;
		Restore lines above to save all variables from all iterations */

        %fedtax ;
        taxfns=taxf;
		
		lastcalc = "federal" ;
		/* Restore lines below to save all variables from all iterations
		if &detail = 2 and iteration = 3 then file resultsf(allvars23.txt) lrecl=25000 ;
		if &detail = 2 and iteration = 3 then put iteration= deductcycle= lastcalc= _all_ ;
		Restore lines above to save all variables from all iterations */

		deductcycle=1 ;

        /*** If there is NOT a state income tax, then skips to end of section ***/

        /*** If there IS a state income tax ***/
        if taxtype ne "none" then do;
 
                /* 1st state tax calculation, then 2nd federal to capture
                deduction for state income tax at federal level*/
                %statetax ;

				
				lastcalc = "state" ;
				/* Restore lines below to save all variables from all iterations
				if &detail = 2 and iteration = 3 then file resultsf(allvars24.txt) lrecl=25000 ;
				if &detail = 2 and iteration = 3 then put iteration= deductcycle= lastcalc= _all_ ;
				Restore lines above to save all variables from all iterations */

                %fedtax ;

				
				lastcalc = "federal" ;
				/* Restore lines below to save all variables from all iterations
				if &detail = 2 and iteration = 3 then file resultsf(allvars25.txt) lrecl=25000 ;
				if &detail = 2 and iteration = 3 then put iteration= deductcycle= lastcalc= _all_ ;
				Restore lines above to save all variables from all iterations */

				deductcycle=2 ;

                /* If either federal or state tax is deductible at state level, or there is a state AMT based on
				federal, or there is a constraint on state itemization status, or if there is a state limitation
				on itemized deductions that depends on the federal calculation of same, or taxnodetail>0, each tax is 
				computed iteratively a total of 4 times */
                if dedfed=1 or xdedfed=1 or sitded=1 or xsitded=1 or taxtype="pctfed" or taxtype="pctfed3" 
					or taxtype="pctfed4" or mintaxtype>0 or itemiz>1 or (itemlim>0 and Fidmaxlim=1) 
					or taxnodetail>0 then do;
                        %statetax ;

						
						lastcalc = "state" ;
						/* Restore lines below to save all variables from all iterations
						if &detail = 2 and iteration = 3 then file resultsf(allvars26.txt) lrecl=25000 ;
						if &detail = 2 and iteration = 3 then put iteration= deductcycle= lastcalc= _all_ ;
						Restore lines above to save all variables from all iterations */

                        %fedtax ;

						
						lastcalc = "federal" ;
						/* Restore lines below to save all variables from all iterations
						if &detail = 2 and iteration = 3 then file resultsf(allvars27.txt) lrecl=25000 ;
						if &detail = 2 and iteration = 3 then put iteration= deductcycle= lastcalc= _all_ ;
						Restore lines above to save all variables from all iterations */

						deductcycle=3 ;

                        %statetax ;

						
						lastcalc = "state" ;
						/* Restore lines below to save all variables from all iterations
						if &detail = 2 and iteration = 3 then file resultsf(allvars28.txt) lrecl=25000 ;
						if &detail = 2 and iteration = 3 then put iteration= deductcycle= lastcalc= _all_ ;
						Restore lines above to save all variables from all iterations */

						%fedtax ;
						
						lastcalc = "federal" ;
						/* Restore lines below to save all variables from all iterations
						if &detail = 2 and iteration = 3 then file resultsf(allvars29.txt) lrecl=25000 ;
						if &detail = 2 and iteration = 3 then put iteration= deductcycle= lastcalc= _all_ ;
						Restore lines above to save all variables from all iterations */

						deductcycle=4 ;
						taxsFDED_3 = taxsFYI ;
						%statetax ;
	
						lastcalc = "state" ;
						/* Restore lines below to save all variables from all iterations
						if &detail = 2 and iteration = 3 then file resultsf(allvars30.txt) lrecl=25000 ;
						if &detail = 2 and iteration = 3 then put iteration= deductcycle= lastcalc= _all_ ;
						Restore lines above to save all variables from all iterations */


						if taxnodetail>0 then do ;
							%fedtax ;
						
							lastcalc = "federal" ;
							/* Restore lines below to save all variables from all iterations
							if &detail = 2 and iteration = 3 then file resultsf(allvars31.txt) lrecl=25000 ;
							if &detail = 2 and iteration = 3 then put iteration= deductcycle= lastcalc= _all_ ;
							Restore lines above to save all variables from all iterations */

							deductcycle=5 ;
							%statetax ;
	
							lastcalc = "state" ;
							/* Restore lines below to save all variables from all iterations
							if &detail = 2 and iteration = 3 then file resultsf(allvars32.txt) lrecl=25000 ;
							if &detail = 2 and iteration = 3 then put iteration= deductcycle= lastcalc= _all_ ;
							Restore lines above to save all variables from all iterations */

						
							lastcalc = "federal" ;
							/* Restore lines below to save all variables from all iterations
							if &detail = 2 and iteration = 3 then file resultsf(allvars31.txt) lrecl=25000 ;
							if &detail = 2 and iteration = 3 then put iteration= deductcycle= lastcalc= _all_ ;
							Restore lines above to save all variables from all iterations */

							deductcycle=6 ;
							taxsFDED_3 = taxsFYI ;
							%statetax ;
	
							lastcalc = "state" ;
							/* Restore lines below to save all variables from all iterations
							if &detail = 2 and iteration = 3 then file resultsf(allvars32.txt) lrecl=25000 ;
							if &detail = 2 and iteration = 3 then put iteration= deductcycle= lastcalc= _all_ ;
							Restore lines above to save all variables from all iterations */
						end ;
                end;
				else taxsFDED_3=taxsFYI ;
        end;
		else taxsFDED_3 = 0 ;
	end;

	/* If there is no federal tax but there is a state tax */
	else if (Ftaxtype="none") then if (taxtype ne "none") then do ;
        %statetax ;
		taxsFDED_3=taxsFYI ;
	end;

	/* Rename key variables from third iteration to preserve them */
	taxf_3 =taxf;
	taxfns_3 =taxfns;
	taxs_3 =taxs;
	taxs1_3 =taxs1;
	taxs2_3 =taxs2;
	Fsstxliab_3 =Fsstxliab;

 	/* Restore income and deductions to initial values */
	&mtrvar = &mtrvar - increment_3 ;
	if mtrvar in ("wagsal1" ,"wagsal2" ,"businc1"
		,"businc2" ,"farminc1" ,"farminc2"
		,"ltcg1" ,"ltcg2" ,"othcg1" 
		,"othcg2" ,"div1" ,"div2" ,"int1"
		,"int2" ,"teint1" ,"teint2" 
		,"pension1" ,"pension2" ,"rentinc1" 
		,"rentinc2" ,"ui1" ,"ui2" ,"ssben1" 
		,"ssben2" ,"partscorp1" ,"partscorp2" 
		,"othinc1" ,"othinc2") then do ;
		income = income - increment_3 ;
	end ;


	/*** Calculate marginal tax rates */

	if mtrvar in ("charity" ,"intpaid" ,"invint" ,"stinctax"
		,"proptax" ,"salestax" ,"taxnodetail" 
		,"medexp" ,"casualty" ,"movex" ,"busex"
		,"miscdedlim" ,"omiscded" ,"childcare") then do ;
    	    mtrfns_3=max(0,(taxfns_3-taxfns_1)/increment);
        	mtrf_3=(taxf_3-taxf_1)/increment;
        	mtrs_3=(taxs_3-taxs_1)/increment;
        	mtr_3=max(0,mtrf_3+mtrs_3);
        	mtrsi_3=mtr_3-mtrfns_3;
			ssmtr_3=0;
			absmtr_3 = abs(mtr_3) ;
			absmtrfns_3 = abs(mtrfns_3) ;
	end;
	else do;
        mtrfns_3=(taxfns_1-taxfns_3)/increment;
        mtrf_3=(taxf_1-taxf_3)/increment;
        mtrs_3=(taxs_1-taxs_3)/increment;
        mtr_3=mtrf_3+mtrs_3;
        mtrsi_3=mtr_3-mtrfns_3;
		ssmtr_3=(Fsstxliab_1-Fsstxliab_3)/increment ;
		absmtr_3 = abs(mtr_3) ;
		absmtrfns_3 = abs(mtrfns_3) ;
	end;

	if max(absmtr_3,absmtrfns_3) < max(absmtr,absmtrfns) then do ;
		increment =increment_3 ; mtrfns =mtrfns_3 ; mtrf =mtrf_3 ;
		mtrs =mtrs_3 ; mtr =mtr_3 ; mtrsi =mtrsi_3 ; ssmtr =ssmtr_3 ;
		taxf_2=taxf; taxfns_2=taxfns; taxs_2=taxs; taxs1_2=taxs1;
		taxs2_2=taxs2; Fsstxliab_2=Fsstxliab ; 
	end ;
  end ;
  else do ;
	mtr_3 = mtr ;
	mtrfns_3 = mtrfns ;
	absmtr_3 = abs(mtr) ;
	absmtrfns_3 = abs(mtrfns) ;
  end ;
  %mend Iteration3 ; 

  %macro detail3 ;
	if (absmtr > &checkMTR or absmtrfns > &checkMTR) and max(absmtr_3,absmtrfns_3) < max(absmtr,absmtrfns) then do ;
		FmtrNORM_2=FmtrNORM/100;	FmtrNORM2_2=FmtrNORM2/100;
		SmtrNORM_2=SmtrNORM/100; SmtrNORM2_2=SmtrNORM2/100;	Fagi_2=Fagi;
		Fssagi_2=Fssagi; Fti_2=Fti; Fti1_2=Fti1; Fti2_2=Fti2;
		Fexempt_2=Fexempt; Fstded_2=Fstded; Fitemded_2=Fitemded;
		Fitemizer_2=Fitemizer; Fitemlost_2=Fitemlost; Fidmaxlim_2=Fidmaxlim;
		FtaxNORM_2=FtaxNORM; FtaxMAXEI_2=FtaxMAXEI; FtaxALTCG_2=FtaxALTCG;
		FtaxINCAVG_2=FtaxINCAVG; FmtrMEI_2=FmtrMEI;	Fdtxliab_bc_2=Fdtxliab_bc;
		FtaxMIN_2=FtaxMIN; Famt_2=Famt;	Famtpref_2=Famtpref; Famti_2=Famti;
		Famtexempt_2=Famtexempt; Famtiae_2=Famtiae; FamtiaeEXCG_2=FamtiaeEXCG;
		Ftamt_2=Ftamt; Fkcarecred_2 = Fkcarecred ; Feic_2=Feic; Fkidcred_2=Fkidcred;
		Fkidcredref_2=Fkidcredref; Feldcred_2=Feldcred ; agi_2=agi;
		agi1_2=agi1; agi2_2=agi2; Sti_2=Sti; Sti1_2=Sti1 ; Sti2_2=Sti2 ;
		exempt_2=exempt ; exempt1_2=exempt1 ; exempt2_2=exempt2 ; stded_2=stded ;
		itemded_2=itemded ; itemded1_2=itemded1 ; itemded2_2=itemded2 ;
		itemizer_s_2=itemizer_s ; retexamt_2=retexamt; lowexamt_2=lowexamt;
		miscex_2=miscex; StaxNORM_2=StaxNORM; sptxliab_2=sptxliab;		
		sptx2liab_2=sptx2liab; StaxALTCG_2=StaxALTCG; StaxASP_2=StaxASP;
		StaxAMIN_2=StaxAMIN; StaxMIN_2=StaxMIN; gencred_2=gencred;
		retcred_2=retcred; retcredref_2=retcredref; lowcred_2=lowcred;
		lowcredref_2=lowcredref; kcarecred_2=kcarecred; marcred_2=marcred;
		StaxAGC_2=StaxAGC; xtaxs_2=xtaxs; xcredit_2=xcredit; StaxAX_2=StaxAX;
		eicstateref_2=eicstateref ; eicstatenoref_2=eicstatenoref ;
		Fsepfiler_2=Fsepfiler ; Ssepfiler_2=Ssepfiler ; propcred_2=propcred;
		FtiEXCG_2=FtiEXCG ; FtaxEXCG_2=FtaxEXCG ; FxtiEXCG_2=FxtiEXCG ; 
		FxtaxEXCG_2=FxtaxEXCG ; FoldEIcredit_2=FoldEIcredit ; Fxtax_2=Fxtax ; Fxti_2=Fxti ;
		dedfit_2=dedfit ; FsstxliabSE1_2=FsstxliabSE1 ; FsstxliabSE2_2=FsstxliabSE2 ;
		localtax_2=localtax ; taxsFDED_2=taxsFDED_3 ; Fchlimbind_2 = Fchlimbind ; chlimbind_2 = chlimbind ;
	end ;
  %mend Detail3 ;

  %iteration2 ;
	%if &detail > 0 %then %Detail2 ;
 
  %if &reverseMTR = 1 %then %do ;
	%Iteration3 ;
	%if &detail > 0 %then %Detail3 ;
  %end ;

%mend MTRcalc ;

%macro NoMTR ;
	/* This macro will execute if incrementquantity = 0, in which case marginal tax rate is not calculated */
	%macro NoMTR1 ;
        mtrfns = . ;
        mtrf =. ;
        mtrs = . ;
        mtr = . ;
        mtrsi = . ;
		ssmtr = . ;
	%mend NoMTR1 ;

	%macro DetailNoMTR ;
		taxsFDED_2 = . ; taxf_2 = . ; taxfns_2 = . ;
		taxs_2 = . ; taxs1_2 = . ; taxs2_2 = . ; Fsstxliab_2 = . ;
		FmtrNORM_2 = . ; FmtrNORM2_2 = . ; SmtrNORM_2 = . ;
		SmtrNORM2_2 = . ; Fagi_2 = . ; Fssagi_2 = . ; Fti_2 = . ; Fti1_2 = . ;
		Fti2_2 = . ; Fexempt_2 = . ; Fstded_2 = . ; Fitemded_2 = . ; 
		Fitemizer_2 = . ; Fitemlost_2 = . ; Fidmaxlim_2 = . ;
		FtaxNORM_2 = . ; FtaxMAXEI_2 = . ; FtaxALTCG_2 = . ; 
		FtaxINCAVG_2 = . ; FmtrMEI_2 = . ; Fdtxliab_bc_2 = . ;
		FtaxMIN_2 = . ; Famt_2 = . ; Famtpref_2 =. ; Famti_2 = . ;
		Famtexempt_2 = . ; Famtiae_2 = . ; FamtiaeEXCG_2 = . ;
		Ftamt_2 = . ; Fkcarecred_2 = . ; Feic_2 = . ; Fkidcred_2 = . ;
		Fkidcredref_2 = . ; Feldcred_2 = . ; agi_2 = . ; agi1_2 = . ;
		agi2_2 = . ; Sti_2 = . ; Sti1_2 = . ; Sti2_2 = . ; exempt_2 = . ;
		exempt1_2 = . ; exempt2_2 = . ; stded_2 = . ; itemded_2 = . ;
		itemded1_2 = . ; itemded2_2 = . ; itemizer_s_2 = . ;
		retexamt_2 = . ; lowexamt_2 = . ; miscex_2 = . ; StaxNORM_2 = . ;
		sptxliab_2 = . ; sptx2liab_2 = . ; StaxALTCG_2 = . ;
		StaxASP_2 = . ; StaxAMIN_2 = . ; StaxMIN_2 = . ; gencred_2 = . ;
		retcred_2 = . ; retcredref_2 = . ; lowcred_2 = . ; lowcredref_2 = . ;
		kcarecred_2 = . ; marcred_2 = . ; StaxAGC_2 = . ; xtaxs_2 = . ;
		xcredit_2 = . ; StaxAX_2 = . ; eicstateref_2 = . ; 
		eicstatenoref_2 = . ; Fsepfiler_2 = . ; Ssepfiler_2 = . ; 
		propcred_2 = . ; FtiEXCG_2 = . ; FtaxEXCG_2 = . ; FxtiEXCG_2 = . ; 
		FxtaxEXCG_2 = . ; FoldEIcredit_2 = . ; Fxtax_2 = . ; Fxti_2 = . ;
		dedfit_2 = . ; FsstxliabSE1_2 = . ; FsstxliabSE2_2 = . ;
		localtax_2 = . ; Fchlimbind_2 = . ; chlimbind_2 = . ;
	%mend DetailNoMTR ;
	
	%NoMTR1 ;
	%if &detail > 0 %then %DetailNoMTR ;

%mend NoMTR ;

%macro CloseDataStep ;
	%macro Liability ;
	/*** Produce tax liability output variables */
	taxf=taxf_1 ;
	taxs=taxs_1 ;
	tax=taxf+taxs ;
	taxsi=tax-taxfns_1 ;
	sstax=Fsstxliab_1 ;

	/* Calculate average tax rates */
	if income>0 then do;
        atr=tax/income ;
        atrf=taxf/income;
        atrs=taxs/income;
        atrsi=taxsi/income;
		ssatr=Fsstxliab_1/income;
	end;
	else do ;
        atr=0;
        atrf=0;
        atrs=0;
        atrsi=0;
		ssatr=0;
	end;

	/* bracket rates */
	mtrfb=FmtrNORM_1;
	mtrfbsp=FmtrNORM2_1;
	mtrsb=SmtrNORM_1;
	mtrsbsp=SmtrNORM2_1;
	%mend liability ;

	%macro Keeper1 ;

	keep
        id statename soi year stateyear fedyear
		filertype deps kids1 kids2 kids3 agenum age agesp blind income 
		wagsal1 wagsal2 businc1 businc2 farminc1 farminc2
		ltcg1 ltcg2 othcg1 othcg2 div1 div2 int1 int2 teint1 teint2 
		pension1 pension2 rentinc1 rentinc2 ui1 ui2 ssben1 ssben2 
		partscorp1 partscorp2 othinc1 othinc2 othadj1 othadj2 
		charity charcg intpaid invint stinctax proptax salestax 
		taxnodetail medexp casualty movex busex miscdedlim omiscded 
		childcare fdcred otaxpref oamtadj avglaginc psincome psded rentpay homeval
        tax taxf taxs taxsi sstax mtr mtrf mtrfns mtrfb mtrfbsp
        mtrs mtrsb mtrsbsp mtrsi ssmtr atr atrf atrs atrsi ssatr
		increment iteration taxf_1 taxf_2 taxfns_1 taxfns_2 
		taxs_1 taxs_2 Fagi_1 Fagi_2 Fssagi_1 Fssagi_2  	
		Fti_1 Fti_2 Fti1_1 Fti1_2 Fti2_1 Fti2_2
		Fsepfiler_1 Fsepfiler_2 Fexempt_1 Fexempt_2 
		Fstded_1 Fstded_2 Fitemded_1 Fitemded_2 
		Fitemizer_1 Fitemizer_2	Fitemlost_1 Fitemlost_2
		Fidmaxlim_1 Fidmaxlim_2	FtaxNORM_1 FtaxNORM_2 
		FtaxMAXEI_1 FtaxMAXEI_2	FtaxALTCG_1 FtaxALTCG_2
		FtaxINCAVG_1 FtaxINCAVG_2 FmtrMEI_1 FmtrMEI_2
		Fdtxliab_bc_1 Fdtxliab_bc_2	FtaxMIN_1 FtaxMIN_2
		Famt_1 Famt_2 Famtpref_1 Famtpref_2
		Famti_1 Famti_2	Famtexempt_1 Famtexempt_2
		Famtiae_1 Famtiae_2	FamtiaeEXCG_1 FamtiaeEXCG_2
		Ftamt_1 Ftamt_2	Fkcarecred_1 Fkcarecred_2
		Feic_1 Feic_2 Fkidcred_1 Fkidcred_2
		Fkidcredref_1 Fkidcredref_2	Feldcred_1 Feldcred_2 
		Fsstxliab_1 Fsstxliab_2 agi_1 agi_2	agi1_1 agi1_2 
		agi2_1 agi2_2 Sti_1 Sti_2	Sti1_1 Sti1_2 Sti2_1 Sti2_2
		Ssepfiler_1 Ssepfiler_1	exempt_1 exempt_2
		exempt1_1 exempt1_2	exempt2_1 exempt2_2
		stded_1 stded_2	itemded_1 itemded_2
		itemded1_1 itemded1_2 itemded2_1 itemded2_2
		itemizer_s_1 itemizer_s_2 retexamt_1 retexamt_2
		lowexamt_1 retexamt_2 miscex_1 miscex_2
		StaxNORM_1 StaxNORM_2 sptxliab_1 sptxliab_2
		sptx2liab_1 sptx2liab_2 StaxALTCG_1 StaxALTCG_2
		StaxASP_1 StaxASP_2	StaxAMIN_1 StaxAMIN_2
		StaxMIN_1 StaxMIN_2	gencred_1 gencred_2
		retcred_1 retcred_2	retcredref_1 retcredref_2
		lowcred_1 lowcred_2	lowcredref_1 lowcredref_2
		marcred_1 marcred_2	kcarecred_1 kcarecred_2
		StaxAGC_1 StaxAGC_2	xtaxs_1 xtaxs_2
		xcredit_1 xcredit_2	StaxAX_1 StaxAX_2
		eicstateref_1 eicstateref_2	eicstatenoref_1 eicstatenoref_2
		propcred_1 propcred_2 Ftaxtype taxtype 
		FsstxliabSE1_1 FsstxliabSE2_1 FsstxliabSE1_2 FsstxliabSE2_2
		localtax_1 localtax_2 taxsFDED_1 taxsFDED_2
		Fchlimbind_1 Fchlimbind_2 chlimbind_1 chlimbind_2 mintaxtype Fzba /* weight */ ;
	run;
	%mend keeper1 ;

	%macro Keeper2 ;
	keep
        id statename soi year stateyear fedyear
        tax taxf taxs taxsi sstax
        mtr mtrf mtrfns mtrfb mtrfbsp
        mtrs mtrsb mtrsbsp mtrsi ssmtr
        atr atrf atrs atrsi ssatr income /* weight */ ;
	run ;
	%mend Keeper2 ;

	%macro ChooseKeep ;
		%if &detail > 0 %then %Keeper1 ;
			%else %Keeper2 ;
	%mend ChooseKeep ;

	%Liability ;
	%ChooseKeep ;
%mend CloseDataStep ;
  

/***************************************************************************************
*           END OF MAKEDATA, ITERATION1, MTRCALC, AND CLOSEDATASTEP MACROS             *
****************************************************************************************/





/**************************************************************************************
***************************************************************************************
***************************************************************************************
***************************************************************************************
***************************************************************************************
*****																			  *****
***** 						D.  FEDTAX MACRO									  *****
*****     		macro that performs federal tax calculations                      *****
*****																			  *****			
***************************************************************************************
***************************************************************************************
***************************************************************************************
***************************************************************************************
***************************************************************************************
***************************************************************************************/
%macro fedtax ; 

/****************************************************************************
*	FEDTAX1 MACRO															*
*	CALCULATE FEDERAL TAXABLE INCOME AND MOST FEDERAL CREDITS				*
*****************************************************************************/
%macro fedtax1 ; 
/***************************************************************************
* Federal social security payroll tax liability                            *
****************************************************************************/

if Ftaxtype = "fedinc" then do ;

/* primary earner, social security tax on wage and salary income */
Fsstxliab1=(Fssrate/100)*min(wagsal1,Fsscap)
    +(Fhicap=0)*(Fhirate/100)*wagsal1
    +(Fhicap>0)*(Fhirate/100)*min(wagsal1,Fhicap);

/* spouse, social security tax on wage and salary income */
Fsstxliab2=(Fssrate/100)*min(wagsal2,Fsscap)
    +(Fhicap=0)*(Fhirate/100)*wagsal2
    +(Fhicap>0)*(Fhirate/100)*min(wagsal2,Fhicap);

/* Start, self-employment tax fix by Brad Heim, Feb. 2007 */
/* primary earner, social security tax on self-employment income */
if seinc1<400 then FsstxliabSE1 = 0 ;
else if fedyear<1990 then FsstxliabSE1 =
	(FssrateSE/100)*min(seinc1,max(0,Fsscap-wagsal1))
	+(FhirateSE/100)*min(seinc1,max(0,Fhicap-wagsal1)) ;
else do ;
	FsstxliabSE1a =       
	(FssrateSE/100)*min((1-FssrateSE/200-FhirateSE/200)*seinc1,max(0,Fsscap-wagsal1))
	+(Fhicap=0)*(FhirateSE/100)*(1-FssrateSE/200-FhirateSE/200)*seinc1
	+(Fhicap>0)*(FhirateSE/100)*min((1-FssrateSE/200-FhirateSE/200)*seinc1,max(0,Fhicap-wagsal1)) ;

	/* Legacy code */
    FsstxliabSE1b = 0;
    FsstxliabSE1 = FsstxliabSE1a + FsstxliabSE1b ;
end;    

/* spouse, social security tax on self-employment income */
if seinc2<400 then FsstxliabSE2=0 ;
else if fedyear<1990 then FsstxliabSE2 =
	(FssrateSE/100)*min(seinc2,max(0,Fsscap-wagsal2))
	+(FhirateSE/100)*min(seinc2,max(0,Fhicap-wagsal2)) ;
else do ;
	FsstxliabSE2a = 
	(FssrateSE/100)*min((1-FssrateSE/200-FhirateSE/200)*seinc2,max(0,Fsscap-wagsal2))
	+(Fhicap=0)*(FhirateSE/100)*(1-FssrateSE/200-FhirateSE/200)*seinc2
 	+(Fhicap>0)*(FhirateSE/100)*min((1-FssrateSE/200-FhirateSE/200)*seinc2,max(0,Fhicap-wagsal2)) ;

	/* Legacy code */
	FsstxliabSE2b = 0;
	FsstxliabSE2 = FsstxliabSE2a + FsstxliabSE2b ;
end;
/* End, self-employment tax fix by Brad Heim, Feb. 2007 */

Fsstxliab=Fsstxliab1+Fsstxliab2+FsstxliabSE1+FsstxliabSE2;


/*************************************************************
* Earnings for calculating child care credits and deductions *
**************************************************************/
if filertype="m" then ei2sp = 
	min(max(labinc1-(fedyear>=1990)*(1/2)*FsstxliabSE1,0),
	max(labinc2-(fedyear>=1990)*(1/2)*FsstxliabSE2,0)) ;
else ei2sp = max(labinc1-(fedyear>=1990)*(1/2)*FsstxliabSE1,0) ;

/********************************************************************************
*  Filing status for married couples.                                           *
*  This only matters before 1948; starting in 1948, married couples are         *
*  assumed to file jointly at the federal level.                                *
*********************************************************************************/
if filertype="m" and Fmultbrk=0 and (comprop ne 1) then Fseparate=1;
else if comprop=1 and filertype="m" and Fmultbrk=0 then Fseparate=2;
else Fseparate=0;
/*********************************************************************************/

/************************************
*    Calculate Federal AGI (Fagi)   *
*************************************/

        /* Excluded capital gains (Fexltcg) */
		Fexltcg=(Fcgexpct/100)*ltcg;

        /* AGI except unemployment compensation and social security */
        Fagi= wagsal + businc + farminc 
		+ (ltcg - Fexltcg) + othcg + div + int + pension + rentinc + partscorp + othinc
        -min(Fdivexamt,div)
        -min(Fdiexamt,div+int)
        -othadj
        -(filertype="m")*((Fmarded=1)*0.05+(Fmarded=2)*0.1)*max(min(labinc1,labinc2,30000),0)
        -(1-Fmovexded)*movex
        -(1-Fbusexded)*busex 
		-(fedyear>=1990)*(1/2)*(FsstxliabSE1+FsstxliabSE2) ;

        /* Unemployment compensation in AGI (Fuiagi) */
        if ui>0 and Funemp>0 then do;
                if Funemp=1 and (filertype="s" or filertype="h") then
                        Fuiagi=min(.5*max(Fagi+ui-20000,0),ui);
                else if Funemp=1 and filertype="m" then
                        Fuiagi=min(.5*max(Fagi+ui-25000,0),ui);
                else if Funemp=2 and (filertype="s" or filertype="h") then
                        Fuiagi=min(.5*max(Fagi+ui-12000,0),ui);
                else if Funemp=2 and filertype="m" then
                        Fuiagi=min(.5*max(Fagi+ui-18000,0),ui);
                else if Funemp=3 then Fuiagi=ui;
        end;
        else Fuiagi=0;
        Fagi=Fagi+Fuiagi;

        /* Social security benefits included in AGI (Fssagi) */
        if ssben>0 and Fssbentax>0 then do;
                /* 1984-93: up to 50% includable */
                if Fssbentax=1 and (Fagi+((Fssr1/100)*ssben))>=Fssb1
                        then Fssagi=min((Fssr1/100)*ssben, (Fssr1/100)*(Fagi+(Fssr1/100)*ssben-Fssb1));
                /* 1994-present: up to 85% includable */
                else if Fssbentax=2 and (Fagi+teint+((Fssr1/100)*ssben))>=Fssb1
                        then Fssagi=min((Fssr2/100)*ssben, (Fssr2/100)*max(Fagi+teint+(Fssr1/100)*ssben-Fssb2,0)
                        +min((Fssr1/100)*ssben,(Fssr1/100)*min((Fssb2-Fssb1),
						max(0,Fagi+teint+(Fssr1/100)*ssben-Fssb1))));
				/* 100% benefit taxation */
				else if Fssbentax=3 then Fssagi=ssben ;
				/* No benefit taxation */
                else Fssagi=0;
        end;
        else Fssagi=0;
        Fagi=Fagi+Fssagi ;

        /* Percentage exemption (applies at federal level only in 1913) */
        Fagi=Fagi*(1-(Fpctex/100));



        /*********************************************************
        *   Total value of federal personal exemptions (Fexempt) *
        **********************************************************/
        Fexempt=Fexpercap*(1+(Filertype="m")+deps)
                + Fexreturn + (Fex_dep*deps) + (Fex_age*agenum) + (Fex_age*blind) ;

        /**************************************************************************
        * Personal exemption phase-out, 1991 and after.                           *
        * Note: 1988-90 phase-out calculated after initial tax computation below  *
        ***************************************************************************/
        if Fexlim=2 and Fagi>=Fminexlim then
                Fexempt=max(Fexempt-(Fagi-Fminexlim)*(Fexlimrate/100)*Fexempt,0);
		else if Fexlim=3 and Fagi>=Fminexlim then
                Fexempt=max(Fexempt-(2/3)*(Fagi-Fminexlim)*(Fexlimrate/100)*Fexempt,(1/3)*Fexempt);
		else if Fexlim=4 and Fagi>=Fminexlim then
                Fexempt=max(Fexempt-(1/3)*(Fagi-Fminexlim)*(Fexlimrate/100)*Fexempt,(2/3)*Fexempt);

		/**********************************************
		* Deduction for child care expenses, 1954-75  *
		***********************************************/
		if childcare>0 and Fkcaretype>0 and Fkcaretype<4 and kids1>0 then do ;
			if Fkcaretype=1 then do ;
				if filertype ne "m" then Fkcareded=min(childcare,600,ei2sp) ;
				else if Fagi<4500 then Fkcareded=min(childcare,600,ei2sp) ;
				else Fkcareded=max(0,min(childcare,600,ei2sp)-max(Fagi-4500,0));
			end;
			else if Fkcaretype=2 then do ;
				if filertype ne "m" then do ; 
					if kids1=1 then Fkcareded=min(childcare,600,ei2sp) ;
					else if kids1>1 then Fkcareded=min(childcare,900,ei2sp) ;
				end ;
				else if Fagi<6000 then do ;
					if kids1=1 then Fkcareded=min(childcare,600,ei2sp) ;
					else if kids1>1 then Fkcareded=min(childcare,900,ei2sp) ;
				end ;
				else do ;
					if kids1=1 then Fkcareded=max(0,min(childcare,600,ei2sp)-max(Fagi-6000,0)) ;
					else if kids1>1 then Fkcareded=max(0,min(childcare,900,ei2sp)-max(Fagi-6000,0)) ;
				end;	
			end;
			else if Fkcaretype=3 then do ;
				if filertype ne "m" then do ; 
					if kids1=1 then Fkcareded=min(childcare,2400,ei2sp) ;
					else if kids1=2 then Fkcareded=min(childcare,3600,ei2sp) ;
					else if kids1>2 then Fkcareded=min(childcare,4800,ei2sp) ;
				end ;
				else if Fagi<18000 then do ;
					if kids1=1 then Fkcareded=min(childcare,2400,ei2sp) ;
					else if kids1=2 then Fkcareded=min(childcare,3600,ei2sp) ;
					else if kids1>2 then Fkcareded=min(childcare,4800,ei2sp) ;
				end ;
				else do ;
					if kids1=1 then Fkcareded=max(0,min(childcare,2400,ei2sp)-.5*max(Fagi-18000,0)) ;
					else if kids1=2 then Fkcareded=max(0,min(childcare,3600,ei2sp)-.5*max(Fagi-18000,0)) ;
					else if kids1>2 then Fkcareded=max(0,min(childcare,4800,ei2sp)-.5*max(Fagi-18000,0)) ;
				end;	
			end;
			else Fkcareded=0 ;
		end;
		else Fkcareded=0 ;

		/**********************************************************************
		* If we do not know the division of state and local tax deductions    *
		* between income taxes and other taxes, we need to infer it based on  *
		* state and local income tax liability computed endogenously by the   *
		* calculator.  This requires extra iterations of the calculator.      *
		***********************************************************************/
		if taxnodetail>0 and iteration=1 then do ;
			if statename="zz" then tax_nonincome = taxnodetail ;
			else if deductcycle = 0 then do ;
				tax_nonincomeA = taxnodetail ;
				tax_nonincome = tax_nonincomeA ;
			end ;
			else if deductcycle = 1 then do ;
				tax_nonincomeB = max(0,taxnodetail - max(0,taxs)) ;
				tax_nonincome = tax_nonincomeB ;
			end ;
			else if deductcycle = 2 then do ;
				tax_nonincomeC = max(0,taxnodetail - max(0,taxs)) ;
				tax_nonincome = tax_nonincomeC ; 
			end ;
			else if deductcycle = 3 then do ;
				tax_nonincomeD = max(0,taxnodetail - max(0,taxs)) ;
				tax_nonincome = tax_nonincomeD ; 
			end ;
			else if deductcycle > 3 then tax_nonincome = tax_nonincomeD ;
		end ;
		else if taxnodetail>0 and iteration>1 then do ;
			if statename="zz" then tax_nonincome = taxnodetail ;
			else if deductcycle=0 then tax_nonincome = tax_nonincomeA ;
			else if deductcycle=1 then tax_nonincome = tax_nonincomeB ;
			else if deductcycle=2 then tax_nonincome = tax_nonincomeC ;
			else if deductcycle>=3 then tax_nonincome = tax_nonincomeD ;
		end ;
		else tax_nonincome=0 ;

        /**********************************************
        *  Federal itemized deductions (Fitemded)     *
        ***********************************************/
        Fitemded=
	        (Fcharded>0)*(fedyear ne 2005)*min(charity,max(0,(Fchlim/100)*Fagi))
			+ (Fcharded>0)*(fedyear=2005)*charity
            + Fintded*(intpaid+invint)
            + taxsFYI*(statename ne "zz") 
			+ stinctax*(statename = "zz")
            + proptax
            + (Fsaleded=1)*salestax
			+ (Fsaleded=2)*max(salestax-(taxsFYI*(statename ne "zz")+stinctax*(statename = "zz")),0)
			+ tax_nonincome
            + (Fmedded>0)*max(0,medexp-(Fmedded/100)*max(Fagi,0))
            + max(0,casualty-(Fcasdedlim/100)*max(Fagi,0)-100)
            + Fmovexded*movex
            + Fbusexded*max(0,busex+miscdedlim-.02*max(Fagi,0))
            + (1-Fbusexded)*miscdedlim
            + omiscded 
			+ (Fkcaretype>0)*(Fkcaretype<4)*Fkcareded ;

		/* Is limit on deductible charity binding? */
		if Fcharded>0 and (charity > (Fchlim/100)*Fagi) and (fedyear ne 2005) then Fchlimbind=1 ;
			else Fchlimbind=0 ;

        /******************************************************************
        *    Federal Itemized deduction limitation starting in 1991       *
        *    Fitemlost = itemized deductions lost to limitation           *
        *    iprotected = itemized deductions not subject to limitation   *
        *    iunprotected = itemized deductions subject to limitation     *
        *******************************************************************/
        If Fidphrate>0 then do;
                iprotected=(Fmedded>0)*max(0,medexp-(Fmedded/100)*max(Fagi,0))
                        + invint + max(0,casualty-(Fcasdedlim/100)*max(Fagi,0)-100);
                iunprotected=Fitemded-iprotected;
				if Fagi>=Fidphthresh then do ;
                	Fitemlost=min(.8*(1-(1/3)*(Fidphrate=2)-(2/3)*(Fidphrate=1))*iunprotected,
						(Fidphrate/100)*(Fagi-Fidphthresh));
                	if .8*(1-(1/3)*(Fidphrate=2)-(2/3)*(Fidphrate=1))*iunprotected
						< (Fidphrate/100)*(Fagi-Fidphthresh)
						then Fidmaxlim=1;
					else Fidmaxlim=0;
				end ;
				Fidsharekept=(iunprotected-Fitemlost)/max(1,iunprotected) ;         
        end;
        else do;
                Fitemlost=0 ;
                Fidmaxlim=0;
				Fidsharekept=1 ;
        end;

        /*****************************************************************************
        *    Federal standard deduction (Fstded)                                     *
        *    Fmaxsd = maximum federal standard deduction                             *
        *     after adjustments for age and dependents                               *
        *    Fminsd = minimum federal standard deduction                             *
        *     after adjustments for age and dependents  	                         *
        ******************************************************************************/
        Fminsd = Fminstded + (Fminstded_d*deps) + (Fminstded_a*agenum) ;
        Fmaxsd = Fmaxstded + (Fmaxstded_d*deps) + (Fmaxstded_a* min(agenum + blind,2)) ;
        if Fpctstded=0 then Fstded = Fmaxsd;
        else Fstded=min(Fmaxsd,max((Fpctstded/100)*max(Fagi,0),Fminsd));

		/*********************************************
		* Non-itemizer charitable deduction, 1982-86 *
		**********************************************/
		if Fcharded=2 then NIcharded=0.25*min(100,min(charity,max(0,(Fchlim/100)*Fagi))) ;
		else if Fcharded=3 then NIcharded=0.25*min(300,min(charity,max(0,(Fchlim/100)*Fagi))) ;
		else if Fcharded=4 then NIcharded=0.5*min(charity,max(0,(Fchlim/100)*Fagi)) ;
		else if Fcharded=5 then NIcharded=min(charity,max(0,(Fchlim/100)*Fagi)) ;
		else NIcharded=0 ;

        /***************************************************************
        *  Determine federal taxable income (Fti)					   * 
		*  and federal itemization status (Fitemizer)				   *	
        ****************************************************************/

		FtiNI=max(0, Fagi - Fexempt - Fstded - NIcharded) ;
		FtiYI=max(0, Fagi - Fexempt - max(Fitemded-Fitemlost-Fzba,0)) ;

		%bracketreader(FtiNI, FtaxNORMNI, Frate, Fbracket, Fbracknum) ;
        %bracketreader(FtiYI, FtaxNORMYI, Frate, Fbracket, Fbracknum) ;

		/* 1981 Rate reduction credit */
		if fedyear=1981 then do ;
			FtaxNORMNI = FtaxNORMNI - 0.0125*FtaxNORMNI ;
			FtaxNORMYI = FtaxNORMYI - 0.0125*FtaxNORMYI ;
		end ;

        /*   Federal personal exemption phase-out, 1988-90    */
        if Fexlim=1 and FtiNI>=Fminexlim then
                FtaxNORMNI = FtaxNORMNI + min(.28*Fexempt, (Fexlimrate/100)*(FtiNI-Fminexlim));
        if Fexlim=1 and FtiYI>=Fminexlim then
                FtaxNORMYI = FtaxNORMYI + min(.28*Fexempt, (Fexlimrate/100)*(FtiYI-Fminexlim));

		/********************************************************************************** 
		Choose federal itemization status to minimize combined federal-state tax liability 
		***********************************************************************************/
		if iteration=1 then do ;
			if (FtaxNORMYI + taxsFYI) < (FtaxNORMNI + taxsFNI) and Fitemded>0 then do ;
				Fti = FtiYI ;
				Fitemizer=1 ;
			end ;
			else do ;
				Fti = FtiNI ;
				Fitemizer=0 ;
			end ;
		end ;
		/****************************************************************** 
		After increment has been added for calculating marginal tax rates,
		hold itemization status constant at analagous step of calculation
		from before increment was added.
		*******************************************************************/
		else do ;
			if deductcycle=0 then Fitemizer=FitemizerA ;
			else if deductcycle=1 then Fitemizer=FitemizerB ;
			else if deductcycle=2 then Fitemizer=FitemizerC ;
			else if deductcycle=3 then Fitemizer=FitemizerD ;
			else if deductcycle=4 then Fitemizer=FitemizerE ;
			else if deductcycle=5 then Fitemizer=FitemizerF ;
			if Fitemizer=0 then Fti=FtiNI ;
			else Fti=FtiYI ;
		end ;


		/**************************************************************
		* FEDERAL CREDITS OTHER THAN CHILD CREDIT					  *	
		* These need to be calculated here because they sometimes	  *
		* interact with the federal AMT or minimum tax. The child	  *
		* credit needs to be calculated at the end because it can	  *
		* depend on things that are not calculated until later        *
		***************************************************************/	

		/***************************************************************
		* Fkcarecred -- Federal credit for child care expenses (1976-) *
		****************************************************************/
		if Fkcaretype>3 and kids1>0 then do ;
			/* 1976 - 1981 */
			if Fkcaretype=4 then do ;
				Fkcarerate=.2 ;
				if kids1=1 then Fkcareded=min(ei2sp,2000,childcare) ;
				else if kids1>1 then Fkcareded=min(ei2sp,4000,childcare) ;
				Fkcarecred=Fkcarerate*Fkcareded ;
			end;
			/* 1982 */
			else if Fkcaretype=5 then do ;
				Fkcarerate=.2 ;
				if kids1=1 then Fkcareded=min(ei2sp,2400,childcare) ;
				else if kids1>1 then Fkcareded=min(ei2sp,4800,childcare) ;
				Fkcarecred=Fkcarerate*Fkcareded ;
			end;
			/* 1983 - 2002 */
			else if Fkcaretype=6 then do ;
				if Fagi<10000 then Fkcarerate=.3 ;
				else if Fagi<28000 then Fkcarerate=max(.2,.3-((Fagi-10000)/18000)*.1) ;
				else Fkcarerate=.2 ;
				if kids1=1 then Fkcareded=min(ei2sp,2400,childcare) ;
				else if kids1>1 then Fkcareded=min(ei2sp,4800,childcare) ;
				Fkcarecred = Fkcarerate*Fkcareded ;
			end ;
			/* 2003 - sunset */ 
			else if Fkcaretype=7 then do ;
				if Fagi<15000 then Fkcarerate=.3 ;
				else if Fagi<43000 then Fkcarerate=max(.2,.35-((Fagi-15000)/28000)*.15) ;
				else Fkcarerate=.2 ;
				if kids1=1 then Fkcareded=min(ei2sp,3000,childcare) ;
				else if kids1>1 then Fkcareded=min(ei2sp,6000,childcare) ;
				Fkcarecred = Fkcarerate*Fkcareded ;
			end ; 
		end ;
		else Fkcarecred=0 ;

		/******************************************************
		* Feldcred -- Federal credit for elderly and disabled *
		* (Also known as "retirement income credit" 		  *
		* (applied 1954-present)							  *
		*******************************************************/
		if Feldctype>0 and agenum>0 then do ;	

			if Feldcagefree=0 or agex<Feldcagefree then FeldA1 = 1 ;
				else FeldA1=0;
			if Feldcagefree=0 or agespx<Feldcagefree then FeldA2 = 1;
				else FeldA2=0 ;

			if Feldctype=1 then do ;
				if agex>=65 then Feldcred1=(Feldcrate/100)*
					min(pension1+div1+int1+rentinc1, max(0, Feldcbase-ssben1-FeldA1*max(0,labinc1 - Feldcex))) ;
				else Feldcred1=0 ;
				if agespx>=65 then Feldcred2=(Feldcrate/100)*
					min(pension2+div2+int2+rentinc2, max(0, Feldcbase-ssben2-FeldA2*max(0,labinc2 - Feldcex))) ;
				else Feldcred2=0 ;
				Feldcred=Feldcred1+Feldcred2 ;
			end ;
		
			else if Feldctype=2 then do ;
				if agex>=65 then Feldcred1=(Feldcrate/100)*
					min(pension1+div1+int1+rentinc1, 
					max(0, Feldcbase-ssben1-FeldA1*max(0,labinc1 - Feldcex2)
					-.5*FeldA1*min(max(0,labinc1-Feldcex),Feldcex2-Feldcex))) ;
				else Feldcred1=0 ;
				if agespx>=65 then Feldcred2=(Feldcrate/100)*
					min(pension2+div2+int2+rentinc2, 
					max(0, Feldcbase-ssben2-FeldA2*max(0,labinc2 - Feldcex2)
					-.5*FeldA2*min(max(0,labinc2-Feldcex),Feldcex2-Feldcex))) ;
				else Feldcred2=0 ;
				Feldcred=Feldcred1+Feldcred2 ;
			end ;		
		
			else if Feldctype=3 then do ;
				if agex>=65 then Feldcred1=(Feldcrate/100)*
					min(pension1+div1+int1+rentinc1, 
					max(0, Feldcbase-ssben1-FeldA1*max(0,labinc1 - Feldcex2)
					-.5*FeldA1*min(max(0,labinc1-Feldcex),Feldcex2-Feldcex))) ;
				else Feldcred1=0 ;
				if agespx>=65 then Feldcred2=(Feldcrate/100)*
					min(pension2+div2+int2+rentinc2, 
					max(0, Feldcbase-ssben2-FeldA2*max(0,labinc2 - Feldcex2)
					-.5*FeldA2*min(max(0,labinc2-Feldcex),Feldcex2-Feldcex))) ;
				else Feldcred2=0 ;
				if agenum=2 and filertype="m" then do ;
					FeldcredJ=(Feldcrate/100)*
						min(pension+div+int+rentinc, 
						max(0, Feldcbase-ssben-FeldA1*max(0,labinc - Feldcex2)
						-.5*FeldA1*min(max(0,labinc-Feldcex),Feldcex2-Feldcex))) ;
				end ;
				else FeldcredJ=0 ;
				Feldcred=max(Feldcred1+Feldcred2,FeldcredJ) ;
			end ;		

			else if Feldctype=4 then do ;
				if agenum=1 then Feldcred = (Feldcrate/100)*
					max(0, Feldcbase-max(0,ssben-Fssagi)-.5*max(0,Fagi-Feldcbase)) ;
				else if agenum=2 then Feldcred = (Feldcrate/100)*
					max(0, Feldcbase-max(0,ssben-Fssagi)-.5*max(0,Fagi-Feldcbase2)) ;
				else Feldcred=0 ;
			end ;

		end ;
		else Feldcred=0 ;

        /*******************************************************
        * Fgencred -- Federal general credit (applied 1975-77) *
        ********************************************************/
        if Fcrpercap>0 then Fgencred=(1 + (filertype="m") + deps)*Fcrpercap;
		else Fgencred=0;

        /**************************************
        * Federal Earned Income Credit (Feic) *
        ***************************************/
        if (fedyear<2002 or (fedyear>2002 and fedyear<2003) or (fedyear>2003 and fedyear<2004) or (fedyear>2004 and fedyear<2005))
			then Fmagi=max(0,Fagi+teint);
			else Fmagi=max(Fagi,0) ;
		earnedinc = max(0, labinc-(fedyear>=1990)*(1/2)*(FsstxliabSE1+FsstxliabSE2)) ;

        if (Feicphin0>0 and kids2=0 and max(earnedinc,Fmagi)<Feiclim0 and earnedinc>0) 
			and ( (age=0 and ((agenum<2 and filertype="m") or agenum=0)) 
			or (age>=25 and age<65) or (agesp>=25 and agesp<65) ) then do;
        	if earnedinc<Feic2bend0 and Fmagi<Feic2bend0   
				then Feic=min((Feicphin0/100)*earnedinc,(Feicphin0/100)*Feic1bend0);
            else do ;
				FeicE = max(0,(Feicphin0/100)*min(earnedinc,Feic1bend0)
				-(Feicphout0/100)*max(0,earnedinc-Feic2bend0));
				FeicY = max(0,(Feicphin0/100)*min(Fmagi,Feic1bend0)
				-(Feicphout0/100)*max(0,Fmagi-Feic2bend0)) ;				
 				Feic=min(FeicE,FeicY) ;
			end ;
        end;
        else if Feicphin1>0 and kids2=1 and max(earnedinc,Fmagi)<Feiclim1 and earnedinc>0 then do;
        	if earnedinc<Feic2bend1 and Fmagi<Feic2bend1   
				then Feic=min((Feicphin1/100)*earnedinc,(Feicphin1/100)*Feic1bend1);
            else do ;
				FeicE = max(0,(Feicphin1/100)*min(earnedinc,Feic1bend1)
				-(Feicphout1/100)*max(0,earnedinc-Feic2bend1));
				FeicY = max(0,(Feicphin1/100)*min(Fmagi,Feic1bend1)
				-(Feicphout1/100)*max(0,Fmagi-Feic2bend1)) ;				
 				Feic=min(FeicE,FeicY) ;
			end ; 
        end;
        else if Feicphin2>0 and kids2>1 and max(earnedinc,Fmagi)<Feiclim2 and earnedinc>0 then do;
        	if earnedinc<Feic2bend0 and Fmagi<Feic2bend0   
				then Feic=min((Feicphin2/100)*earnedinc,(Feicphin2/100)*Feic1bend2);
            else do ;
				FeicE = max(0,(Feicphin2/100)*min(earnedinc,Feic1bend2)
				-(Feicphout2/100)*max(0,earnedinc-Feic2bend2));
				FeicY = max(0,(Feicphin2/100)*min(Fmagi,Feic1bend2)
				-(Feicphout2/100)*max(0,Fmagi-Feic2bend2)) ;				
 				Feic=min(FeicE,FeicY) ;
			end ;
        end;
        else Feic=0;
		if Feiciilim>0 then do ;
			if (int1+int2+teint1+teint2+div1+div2+ltcg1+ltcg2+max(rentinc1,0)+max(rentinc2,0))>=Feiciilim
				then Feic=0 ;
		end ;

%mend fedtax1 ; 
%fedtax1 ;		



/************************************************************************
* FEDTAX2 MACRO															*
* NORMAL TAX CALCULATION, ALTERNATIVE CAPITAL GAINS TAX CALCULATIONS	*
* MAXIMUM TAX ON EARNED INCOME, INCOME AVERAGING						*
* FEDERAL TAX LIABILITY BEFORE CREDITS									*
*************************************************************************/

%macro fedtax2 ; 
        /**************************************************************************
        *   "Normal" federal tax calculation                                      *
		*   (Note: from 1913-1945, this is actually the "surtax")				  *
        *   FtaxNORM = normal federal tax liability before credits                *
        *   FmtrNORM = statutory marginal tax rate in applicable tax bracket      *
        ***************************************************************************/
        %bracketreader(Fti, FtaxNORM, Frate, Fbracket, Fbracknum) ;
        FmtrNORM=brackmtr;
        FmtrNORM1=brackmtr;
        FmtrNORM2=brackmtr;

		/* 1981 Rate reduction credit */
		if fedyear=1981 then FtaxNORM = FtaxNORM - 0.0125*FtaxNORM ;

        /*****************************************************
        *   Federal personal exemption phase-out, 1988-90    *
        ******************************************************/
        if Fexlim=1 and Fti>=Fminexlim then
                FtaxNORM = FtaxNORM + min(.28*Fexempt, (Fexlimrate/100)*(Fti-Fminexlim));

		/************************************************************************
		Initialize FtiEXCG to equal Fti.
		Value of FtiEXCG will be changed to exclude capital gains where 
		appropriate.
		*************************************************************************/
		FtiEXCG = Fti ;

		/*************************************************************************
		* Alternative capital gains calculations, 1948-present 					 *
		**************************************************************************
        *    cgmax1, (1948-69, 1981) 			                                 *
        *    Re-calculate normal tax excluding gains, tax gains			         *
		*	 separately at a flat rate. Same feature also applies 1922-33,		 *
		*    1938-47, calculated separately above.								 *
        **************************************************************************/
        if Fsptx="cgmax1" and Fedyear>=1948 and ltcg ne 0 and
   		    (FmtrNORM *(1-(Fcgexpct/100)) >  Fsptxrate) 
			 then do;
			 	/* In 1981, the input variable "oamtadj" may be used to provide
			 	information about the portion of ltcg that was realized after
			 	June 9, 1981, which are the only gains subject to the alternative
			 	calculation */
			 	if (Fedyear=1981 and oamtadj ne 0) then do ;
					if oamtadj > 0 then do ;
						/********************************************************
						* Re-calculate taxable income, excluding capital  		*
						* gains													*
						*********************************************************/
						/* single, HoH, or joint */
                		FtiEXCG = max(0, Fti - (1-(Fcgexpct/100))*max(oamtadj,0));

						/******************************************************
						* Calculate alternative capital gains tax liability   *
						* Note that the 1981 federal rate reduction credit    *
						* is allowed for purposes of computing the 			  *
						* alternative tax on capital gains.					  *
						*******************************************************/
                		%bracketreader(FtiEXCG, FtaxEXCG, Frate, Fbracket, Fbracknum) ;
                		FtaxALTCG = FtaxEXCG - 0.0125*FtaxEXCG + (Fsptxrate/100)*max(oamtadj,0) ;						
					end ;
					else FtaxALTCG = FtaxNORM ;
				end ;
			 	else do ; 
					/********************************************************
					* Re-calculate taxable income, excluding capital  		*
					* gains													*
					*********************************************************/
					/* single, HoH, or joint */
                	FtiEXCG = max(0, Fti - (1-(Fcgexpct/100))*max(ltcg,0));

					/******************************************************
					* Calculate alternative capital gains tax liability   *
					* Note that the 1981 federal rate reduction credit    *
					* is allowed for purposes of computing the 			  *
					* alternative tax on capital gains.					  *
					*******************************************************/
                	%bracketreader(FtiEXCG, FtaxEXCG, Frate, Fbracket, Fbracknum) ;
                	FtaxALTCG = FtaxEXCG - (Fedyear=1981)*0.0125*FtaxEXCG + (Fsptxrate/100)*max(ltcg,0) ;
				end ; 
		end ;

        /**************************************************************************
        *    cgmax2: (1987, 1991-96)                                              *
        *    A maximum rate is applied to gains. Portion of gains already taxed   *
        *    at lower rates remain taxed at lower rates.                          *
        **************************************************************************/
        else if Fsptx="cgmax2" and FmtrNORM>Fsptxrate and ltcg ne 0 then do;
                /* 1987 */
                if Fedyear=1987 then do;
                        if Fti-ltcg>=Fb4 then do;
                                FtiEXCG=max(0, Fti-ltcg);
                                %bracketreader(FtiEXCG, FtaxEXCG, Frate, Fbracket, Fbracknum) ;
                                FtaxALTCG = FtaxEXCG + (Fsptxrate/100)*ltcg ;
                        end;
                        else if Fti > Fb4 and Fti-ltcg < Fb4 then do;
                                %bracketreader(Fb4, FtaxFb4, Frate, Fbracket, Fbracknum) ;
                                FtaxALTCG = FtaxFb4 + (Fsptxrate/100)*(Fti-Fb4) ;
                        end;
						else FtaxALTCG=FtaxNORM ;
                end;
                /* 1991-96 */
                else do;
                        if Fti-ltcg >= Fb2 then do;
                                FtiEXCG=max(0, Fti-ltcg);
                                %bracketreader(FtiEXCG, FtaxEXCG, Frate, Fbracket, Fbracknum) ;
                                FtaxALTCG = FtaxEXCG + (Fsptxrate/100)*ltcg;
                        end;
                        else if Fti > Fb2 and Fti-ltcg < Fb2 then do;
                                %bracketreader(Fb2, FtaxFb2, Frate, Fbracket, Fbracknum) ;
                                FtaxALTCG = FtaxFb2 + (Fsptxrate/100)*(Fti-Fb2) ;
                        end;
						else FtaxALTCG=FtaxNORM ;
                end;
        end;

        /********************************************************************
        *    cgmax3: 1972-78                                                *
        *    Gains below threshold taxed at reduced rate. Gains above       *
        *    threshold taxed at ordinary rates times (1-exclusion rate).    *
        *    Note that Fsptxrate for this version of cgmax refers to        *
        *    tax rate on gains net of exclusion, whereas in the other       *
        *    versions of cgmax, Fsptxrate is the rate on gross gains.       *
        ********************************************************************/
        else if Fsptx="cgmax3" and FmtrNORM > Fsptxrate and ltcg ne 0 then do;
                FtiEXCG=max(0, Fti-(ltcg - Fexltcg));
                %bracketreader(FtiEXCG, FtaxEXCG, Frate, Fbracket, Fbracknum) ;
                if ltcg < Fsptxex then
                        FtaxALTCG = FtaxEXCG + (Fsptxrate/100)*(ltcg-Fexltcg) ;
                else do;
                        FtiEXCG2= FtiEXCG+(1-(Fcgexpct/100))*Fsptxex;
                        %bracketreader(FtiEXCG2, FtaxEXCG2, Frate, Fbracket, Fbracknum) ;
                        FtaxALTCG = FtaxEXCG + (Fsptxrate/100)*(1-(Fcgexpct/100))*Fsptxex
                                + (FtaxNORM-FtaxEXCG2);
                end;
        end;

        /*************************************************************
        *    cgmax4: 1970-71                                         *
        *    Same as cgmax1, but with two brackets and rates         *
        *    applied to gains.                                       *
        *************************************************************/
        else if Fxtaxtype="cgmax4" and (FmtrNORM*(1-(Fcgexpct/100)) > Fxr1) and ltcg ne 0 then do;
                FtiEXCG = max(0, Fti-(ltcg-Fexltcg));
                %bracketreader(FtiEXCG, FtaxEXCG, Frate, Fbracket, Fbracknum) ;
                %bracketreader(ltcg, FtaxCGa, Fxrate, Fxbracket, Fxbracknum) ;
                FtaxALTCG=FtaxEXCG+FtaxCGa ;
        end;

        /********************************************************************************
        *    cgmax5 and cgmax6: 1997-present                                            *
        *    Gains taxed at reduced rates, with rate depending on which bracket(s)      *
        *    the gains would fall into in normal tax.                                   *
        *    FtiEXCG = taxable income less long-term gains                              *
		*	 CGa = LT gains taxed at lower rate											*
        *    FtaxCGa = alt. tax on LT cap gains that would be taxed in lower bracket(s) *
		*    CGb = LT gains taxed at higher rate										*
        *    FtaxCGb = alt. tax on LT cap gains that would be taxed in 2nd bracket      *
		*    Starting in 2003, cgmax6 applies, and dividends are treated like ltcg		*
        *********************************************************************************/
        else if (Fxtaxtype="cgmax5" and ltcg ne 0) or (Fxtaxtype="cgmax6" and ((ltcg ne 0) or (div ne 0))) then do;
				if Fxtaxtype="cgmax6" then ltcgx = ltcg+div ;
					else ltcgx=ltcg ;
                FtiEXCG=max(0, Fti-ltcgx);
                %bracketreader(FtiEXCG, FtaxEXCG, Frate, Fbracket, Fbracknum) ;
				
                /* gains taxed at 1st CG rate */
                if FtiEXCG < Fxb2 then do ;
					CGa = max(0,min(Fti,Fxb2)-FtiEXCG) ;
					FtaxCGa=(Fxr1/100)*CGa ;
				end ; 
                else do ;
					CGa = 0;
					FtaxCGa=0;
				end ;

                /* gains taxed at 2nd CG rate */
                CGb = max(0,min(Fti,ltcgx)-CGa) ;
				FtaxCGb = (Fxr2/100)*CGb ;	

                /* tax liability with CG adjustment */
                FtaxALTCG = FtaxEXCG + FtaxCGa + FtaxCGb ;
        end;

		/* Cases where alternative capital gains tax computations are not applicable */
        else do ;
			FtaxALTCG = FtaxNORM;
			CGa=0;
			CGb=0;
			FtaxCGa=0;
			FtaxCGb=0;
			if Fseparate=1 then do ;
				FtaxALTCG1 = FtaxNORM1 ;
				FtaxALTCG2 = FtaxNORM2 ;
			end ;
		end;

        /************************************************************************************
        *    Federal income averaging (1964-86)                                             *
        *    FtaxINCAVG = federal income tax liabilty after income-averaging provisions     *
        *    FtiA1 = Amount of taxable income above which income averaging rate applies     *
        *    FtiA2 = FtiA1 + (20% of difference between taxable income and FtiA1)           *
        *    The average rate on FtiA2 is applied to all taxable income above FtiA2         *
        *************************************************************************************/
        if avglaginc>0 and Fincavg>0 and (int(Fti)-avglaginc)>max((Fincavg/100)*avglaginc,3000) then do;
	        FtiA1 = (1+(Fincavg/100))*avglaginc;
            FtiA2 = FtiA1 + (((Fedyear<1984)+(1984<Fedyear<1985))*0.2+((Fedyear=1984)+(Fedyear>=1985))*0.25)*(Fti - FtiA1);
            %bracketreader(FtiA1, FtaxA1, Frate, Fbracket, Fbracknum) ;
            %bracketreader(FtiA2, FtaxA2, Frate, Fbracket, Fbracknum) ;
            FtaxINCAVG = FtaxA1 + ((FtaxA2 - FtaxA1)/max(1,FtiA2 - FtiA1))*(Fti - FtiA1) ;
			/* 1981 federal rate reduction credit recomputed for income averaging purposes */
			if fedyear=1981 then FtaxINCAVG = FtaxINCAVG - 0.0125*FtaxINCAVG ;
			/* Recompute income averaging with alternative capital gains computation, 1981 */
        	if Fsptx="cgmax1" and fedyear=1981 and ltcg ne 0 and (FmtrNORM *(1-(Fcgexpct/100)) >  Fsptxrate) and oamtadj ne -1 then do;
				if oamtadj=0 then do ;
					/********************************************************
					* Re-calculate taxable income, excluding capital  		*
					* gains													*
					*********************************************************/
	            	FtiEXCG = max(0, Fti - (1-(Fcgexpct/100))*max(ltcg,0));
		            FtiA2 = FtiA1 + (((Fedyear<1984)+(1984<Fedyear<1985))*0.2+((Fedyear=1984)+(Fedyear>=1985))*0.25)*max(0,FtiEXCG - FtiA1);
		            %bracketreader(FtiA1, FtaxA1, Frate, Fbracket, Fbracknum) ;
		            %bracketreader(FtiA2, FtaxA2, Frate, Fbracket, Fbracknum) ;
		            FtaxINCAVGEXCG = FtaxA1 + ((FtaxA2 - FtaxA1)/max(1,FtiA2 - FtiA1))*(Fti - FtiA1) ;


		   	        FtaxINCAVG = min(FtaxINCAVGEXCG - 0.0125*FtaxINCAVGEXCG + (Fsptxrate/100)*max(ltcg,0), FtaxINCAVG) ;
				end ;
				else do ;
					/********************************************************
					* Re-calculate taxable income, excluding capital  		*
					* gains													*
					*********************************************************/
	            	FtiEXCG = max(0, Fti - (1-(Fcgexpct/100))*max(oamtadj,0));
		            FtiA2 = FtiA1 + (((Fedyear<1984)+(1984<Fedyear<1985))*0.2+((Fedyear=1984)+(Fedyear>=1985))*0.25)*max(0,FtiEXCG - FtiA1);
		            %bracketreader(FtiA1, FtaxA1, Frate, Fbracket, Fbracknum) ;
		            %bracketreader(FtiA2, FtaxA2, Frate, Fbracket, Fbracknum) ;
		            FtaxINCAVGEXCG = FtaxA1 + ((FtaxA2 - FtaxA1)/max(1,FtiA2 - FtiA1))*(Fti - FtiA1) ;

		   	        FtaxINCAVG = min(FtaxINCAVGEXCG - 0.0125*FtaxINCAVGEXCG + (Fsptxrate/100)*max(oamtadj,0), FtaxINCAVG) ;
				end ;
			end ;
        end;
		else FtaxINCAVG = FtaxNORM;


        /*******************************************************
        *     Maximum tax on earned income, 1971-81            *
        *     Feti = federal earned taxable income             *
        *     FtaxMEI = maximum tax liability on earned income *
        *     FtaxMAXEI = maximum overall tax liability        *
        *******************************************************/
        if Fmaxeitype>0 and FmtrNORM > Fmaxeirate then do;
                /* Base of maximum tax */
                /* 1971-75 */
                if Fmaxeitype=1 then do ;
					if psincome=-1 then psincomeX = nflabinc ;
						else psincomeX = psincome ;
					if psded=-1 then psdedX = busex+movex ;
						else psdedX = psded ;
                    Feti = max(0, min(1,max(0,psincomeX-psdedX)/max(1,Fagi))*Fti
                        - max(0, otaxpref+Fexltcg-30000)) ;
				end ;
                /* 1976 */
                else if Fmaxeitype=2 then do ;
					if psincome=-1 then psincomeX = nflabinc ;
						else psincomeX = psincome ;
					if psded=-1 then psdedX = busex+movex ;
						else psdedX = psded ;
					iprotected = (Fmedded>0)*max(0,medexp-(Fmedded/100)*max(Fagi,0))+max(0,casualty-100) ;
                    Feti = max(0,min(1,max(0,psincomeX-psdedX)/max(1,Fagi))*Fti
                        - max(0, otaxpref+Fexltcg
                        +Fitemizer*max(0,(Fitemded-iprotected)-.6*max(Fagi,0))
						-30000)) ;
				end ;
                /* 1977-78 */
                else if Fmaxeitype=3 then do ;
					if psincome=-1 then psincomeX = nflabinc+pension ;
						else psincomeX = psincome ;
					if psded=-1 then psdedX = busex+movex ;
						else psdedX = psded ;
					iprotected = (Fmedded>0)*max(0,medexp-(Fmedded/100)*max(Fagi,0))+max(0,casualty-100) ;
                    Feti = max(0,min(1,max(0,psincomeX-psdedX)/max(1,Fagi))*Fti
                        - max(0, otaxpref + (Fedyear=1977)*Fexltcg
                        +Fitemizer*max(0,Fitemded-iprotected-.6*max(Fagi,0)))) ;
				end ;
                /* 1979-81 */
                else if Fmaxeitype=4 then do ;
					if psincome=-1 then psincomeX = nflabinc+pension ;
						else psincomeX = psincome ;
					if psded=-1 then psdedX = busex+movex ;
						else psdedX = psded ;
					iprotected = (Fmedded>0)*max(0,medexp-(Fmedded/100)*max(Fagi,0))
						+max(0,casualty-100)
                        +max(taxsFYI,0)
						+proptax
						+salestax
						+tax_nonincome 
						+(statename="zz")*max(stinctax,0) ;
                    Feti = max(0,min(1,max(0,psincomeX-psdedX)/max(Fagi,1))*Fti
                        - max(0, otaxpref
                        +Fitemizer*max(0,Fitemded-iprotected-.6*max(Fagi-iprotected,0)))) ;
				end ;

                /* Normal tax on Feti */
                %bracketreader(Feti, FtaxETI, Frate, Fbracket, Fbracknum) ;

				/* MAXIMUM TAX CALCULATION FOR YEARS OTHER THAN 1981 */
				if fedyear ne 1981 then do ;
	                /* Maximimum tax on Feti. Bracketreader is modified to limit
	                   top rate on Feti to Fmaxeirate */
	                FtaxMEI = 0;
	                found=0;
	                i=0;
	                j=0;
	                do until (found=1);
                        i=i+1;
                        j=i+1;
                        if i >= Fbracknum then do;
                                FtaxMEI = FtaxMEI +
                                    (min(Frate{i} , Fmaxeirate)/100)
                                    * max((Feti - Fbracket{i} ),0);
                                FmtrMEI = min(Frate{i} , Fmaxeirate) ;
                                found=1;
                        end;
                        else if Feti < Fbracket{j} then do;
                                FtaxMEI = FtaxMEI +
                                	(min(Frate{i} , Fmaxeirate)/100)
                                    *max(( Feti - Fbracket{i} ),0);
                                FmtrMEI = min(Frate{i} , Fmaxeirate) ;
                                found=1;
                        end;
                        else do;
                                FtaxMEI = FtaxMEI
                                + (min(Frate{i} , Fmaxeirate)/100)*( Fbracket{j} - Fbracket{i} );
                        end;
                	end;

                	/* Calculation of total tax liability after maximum tax, including
                	any adjustments for alternative tax on capital gains */
                	if Fmaxeitype=4 then FtaxMAXEI = FtaxMEI + (FtaxNORM - FtaxETI) ;
					else FtaxMAXEI = min(FtaxMEI + (FtaxNORM-FtaxETI), FtaxMEI + (FtaxALTCG-FtaxETI)) ;
				end ;

				/* MAXIMUM TAX CALCULATION FOR 1981 */
				else if fedyear=1981 then do ;

					/* brackgt50 = bottom of first bracket with rate higher than 50% */
					if filertype="m" or filertype="h" then brackgt50 = fb12 ;
						else brackgt50 = fb14 ;

                	%bracketreader(brackgt50, FtaxBrackgt50, Frate, Fbracket, Fbracknum) ;

					FtaxMAXEI = 0.5*max(0,Feti-brackgt50) + (max(0,(FtaxNORM/(1-0.0125))-FtaxETI) + FtaxBrackgt50)*(1-0.0125) ;

					FtiEXCG = max(0, Fti - (1-(Fcgexpct/100))*max(oamtadj,0));

					if (oamtadj ne -1) and min(Feti,FtiEXCG) > brackgt50 then do ;

						%bracketreader(FtiEXCG, FtaxEXCG, Frate, Fbracket, Fbracknum) ;

						FtaxMAXEI = min(FtaxMAXEI,
										0.5* max(0,min(Feti,FtiEXCG)-brackgt50)
										+ (1-0.0125)*(FtaxBrackgt50 + max(0,FtaxEXCG - FtaxETI))
										+ (Fsptxrate/100)*max(oamtadj,0)
										) ;
					end ;

				end ;
        end;
        else do;
                FtaxMAXEI=FtaxNORM ;
                FmtrMEI=0;
        end;


        /*******************************************************************
        *  Federal tax liability before credits and after maximum taxes    *
        *  but before minimum taxes (Fdtxliab_bc), 1948-present            *
        ********************************************************************
        *   Note that taxpayer had to choose between income averaging      *
        *   or maximum tax on earned income, which is reflected here.      *
        *   Code below selects the minimum of possible tax liabilities     *
        *   under different computations. If any or all of the alternative *
        *   or maximum taxes do not apply, they have already been set to   *
        *   equal FtaxNORM.                                                *
        ********************************************************************/
		if fedyear>=1948 then do ;
			Fsepfiler=0 ;
        	Fdtxliab_bc = min(FtaxNORM, FtaxALTCG, FtaxINCAVG, FtaxMAXEI);
		end ;
		else do ;
			FtaxINCAVG=0 ;
			FtaxMAXEI=0 ;
		end; 


%mend fedtax2 ;		
%fedtax2 ;			




/*****************************************************************************************
* FEDTAX3 MACRO																			 *
* FEDERAL MINIMUM TAX AND ALTERNATIVE MINIMUM TAX										 *
******************************************************************************************/

%macro fedtax3 ;	
        /********************************************************************
        *   Federal minimum tax (a.k.a. additional tax for tax preferences) *
        *   1970-82                                                         *
        *   Ftaxpref = federal tax preference items                         *
        *       FtaxMIN = additional tax liability due to minimum tax       *
        *********************************************************************/
        /**********************************************************************************
        *   Federal alternative minimum tax (1979-present)                                *
        *   Famtpref = federal AMT preferences                                            *
        *   Famti = alternative minimum taxable income (calculated before AMT exmeptions) *
        *   Famtexempt = allowable AMT exemption                                          *
        *   Famtiae = Famti less allowable AMT exemption                                  *
        *   Ftamt = Tentative AMT (AMT before subtracting income tax liability)           *
        *   Famt = increase in total tax liability caused by AMT                          *
		*   SI indicates a variable re-calculated after switching itemization status	  *
        ***********************************************************************************/
        If Fmintaxtype>0 or (famttype>0 and ((Fagi+Fexltcg+otaxpref+oamtadj)>Famtex or mintaxtype>0)) then do ; 

			/*****************************************
			* Minimum tax 							 *
			******************************************/
	        if Fmintaxtype>0 then do ;
                /* 1970-75 */
                if Fmintaxtype=1 then Ftaxpref = Fexltcg + otaxpref ;
                /* 1976-78 */
                else if Fmintaxtype=2 then do ;
						iprotected = (Fmedded>0)*max(0,medexp-(Fmedded/100)*max(Fagi,0))+max(0,casualty-100) ;
						Ftaxpref =
                        Fexltcg + otaxpref
                        + Fitemizer*max(0,min(Fagi-Fexempt,Fitemded-iprotected-.6*max(Fagi,0))) ;
				end ;
                /* 1979-82 */
                else if Fmintaxtype=3 then Ftaxpref = otaxpref;

                /* Minimum tax calculation */
                FtaxMIN = max(0,(Fmintaxrate/100)
					*max(0,Ftaxpref-max(10000,.5*max(0, Fdtxliab_bc-Feldcred-Fkcarecred-fdcred)))
                    -max(0,Feldcred+Fkcarecred-max(0,Fdtxliab_bc-fdcred)));
	        end;
	        else do ;
                FtaxMIN=0 ;
                Ftaxpref=0 ;
	        end;

				/****************************************
				* Alternative minimum tax 				*
				*****************************************/
                /* Calculate AMTI */
                /* 1979-82 */
                if (Famttype=1 or Famttype=2) then do;
						iprotected = 
							(Fmedded>0)*max(0,medexp-(Fmedded/100)*max(Fagi,0))
							+max(0,casualty-100)
							+taxsFYI
                        	+proptax
							+salestax
							+tax_nonincome
							+(statename="zz")*stinctax ;

                        Famtpref = Fexltcg 
							+ Fitemizer*max(0, Fitemded - iprotected -0.6*max(0,Fagi - iprotected)) ;

                        Famti = max(0, Fagi - max(Fitemizer*Fitemded, Fzba) - Fexempt + Famtpref) ;
                end;
                /* 1983-86 */
                else if famttype=3 then do;
                        Famtpref = Fexltcg + min(div, Fdivexamt) + otaxpref ;
                        Famti = Fagi + Famtpref
                            - Fitemizer*(
								min(charity,max(0,(Fchlim/100)*Fagi)) 
								+ max(0,medexp-.1*max(Fagi,0))
								+ intpaid + invint
								+ max(0,casualty-(Fcasdedlim/100)*max(Fagi,0)-100)
								) ;
                end;
                /* 1987-present */
				/* Note: medical expenses fixed July 2007 and March 2008 -- JMB */
                else if (Famttype>3) then do;
                	Famtpref=otaxpref + Fitemizer*((Famttype=4)+(Famttype=5))*charcg ;
                    Famti = Fagi + otaxpref + oamtadj
						- Fitemizer*Fitemded 
                    	+ Fitemizer*(taxsFYI+proptax+tax_nonincome+(statename="zz")*stinctax
						+ (Fsaleded=2)*max(salestax-(taxsFYI*(statename ne "zz")+stinctax*(statename = "zz")),0)
						+ min(.025*max(Fagi,0),max(0,medexp-(Fmedded/100)*max(Fagi,0)))
						+ max(0,busex+miscdedlim-.02*max(Fagi,0))
                        +((Famttype=4)+(Famttype=5))*charcg) ;
                end;
                /* Calculate AMT exemption after any phase-outs, and Famtiae */
                Famtexempt=max(0, Famtex-(Famtexrate/100)*max(0,Famti-Famtexth));
                Famtiae=max(0, Famti-Famtexempt);

                /* Calculate Ftamt */
                /* 1979-80, 82-96, 1981 if all gains are from before June 9 */
                if ((Famttype ne 2) or oamtadj=-1) and (Famttype ne 7) then do;
                        %bracketreader(Famtiae, Ftamt, Famtrate, Famtbracket, Famtbrkn) ;
                end;
                /* 1981 if all gains are from after June 9 */
                else if (Famttype=2 and oamtadj=0) then do;
						Famtr3=25;
                        %bracketreader(Famtiae, Ftamt1, Famtrate, Famtbracket, Famtbrkn) ;                    
                        FamtEXCG=max(0,Famtiae-Fexltcg);
						Famtr3=20;
                        %bracketreader(FamtEXCG, Ftamt2, Famtrate, Famtbracket, Famtbrkn) ;                        
                        Ftamt=min(Ftamt1, Ftamt2+.2*Fexltcg);
						Famtr3=25;
                end;
				/* 1981 if we have information on amount of gains after June 9 */
                else if (Famttype=2 and oamtadj>0) then do;
						FexltcgLate = (Fcgexpct/100)*max(oamtadj,0) ;
						Famtr3=25;
                        %bracketreader(Famtiae, Ftamt1, Famtrate, Famtbracket, Famtbrkn) ;                    
                        FamtEXCG=max(0,Famtiae-FexltcgLate);
						Famtr3=20;
                        %bracketreader(FamtEXCG, Ftamt2, Famtrate, Famtbracket, Famtbrkn) ;                        
                        Ftamt=min(Ftamt1, Ftamt2+.2*FexltcgLate);
						Famtr3=25;
                end;
                /* 1997-present */
                else if (Famttype=7) then do;
                    %bracketreader(Famtiae, Ftamt, Famtrate, Famtbracket, Famtbrkn) ;

					/* For those subject to alternative capital gains computation */
					if (Fxtaxtype="cgmax5" and ltcg ne 0) or 
					(Fxtaxtype="cgmax6" and ((ltcg ne 0) or (div ne 0))) then do;
						if Fxtaxtype="cgmax6" then ltcgx=ltcg+div;
							else ltcgx=ltcg;
                		FamtiaeEXCG=max(0, Famtiae-min(Famtiae,ltcgx));
                		%bracketreader(FamtiaeEXCG, FtamtEXCG, Famtrate, Famtbracket, Famtbrkn) ;
				
                		/* gains taxed at 1st CG rate */
						CGaX = max(0,min(CGa,min(Famtiae,ltcgx))) ;
						FtaxCGaX = (Fxr1/100)*CGaX;

                		/* gains taxed at 2nd CG rate */
						CGbX = max(0,min(Famtiae,ltcgx)-CGaX);
						FtaxCGbX = (Fxr2/100)*CGbX;

                		/* tax liability with CG adjustment */
                		FtamtALTCG = FtamtEXCG + FtaxCGaX + FtaxCGbX ;

						Ftamt = min(Ftamt,FtamtALTCG) ;
        			end;
					else do ;
						CGaX=0 ;
						CGbX=0 ;
						FtamtEXCG=Ftamt ;
						FtamtALTCG=Ftamt ;
					end ;
                end;

                /* Calculate AMT liability */
	            if Famttype<=3 then Famt=max(0, Ftamt-max(0,Fdtxliab_bc-Feldcred-Fkcarecred-fdcred)-FtaxMIN);
					else Famt=max(0,Ftamt-Fdtxliab_bc) ;
		end ;
		else do;
                Famt=0;
                Ftamt=0;
                Famti=0;
                Famtiae=0;
                Famtpref=0;
                FtaxMIN=0 ;
                Ftaxpref=0 ;
        end;
%mend fedtax3 ; 
%fedtax3 ;		


/*******************************************************************************
* FEDTAX4 MACRO																   *
* IF SUBJECT TO FEDERAL AMT OR MINIMUM TAX, OR IF FEDERAL ITEMIZATION DECISION *
* CONSTRAINS STATE ITEMIZATION DECISION, OR IF STATE MINIMUM TAX IS A 		   *
* PERCENTAGE OF FEDERAL AMT, THEN RE-DO CALCULATIONS IN FEDTAX2    			   * 
* AND FEDTAX3 WITH SWITCHED ITEMIZATION STATUS                                 *
********************************************************************************/
%macro fedtax4 ; 
if Famt>0 or FtaxMIN>0 or itemiz>1 or mintaxtype=5 then do;
	/****************************************** 
	Rename key variables to save their values 
	*******************************************/
	FtaxNORM_X = FtaxNORM ; 
	FtaxMAXEI_X = FtaxMAXEI ; 
	FtaxALTCG_X = FtaxALTCG ;
	FtaxINCAVG_X = FtaxINCAVG ; 
	FmtrMEI_X = FmtrMEI ; 
	Fdtxliab_bc_X = Fdtxliab_bc ; 
	FtaxMIN_X = FtaxMIN ; 
	Fti_X = Fti ;
	FtiEXCG_X = FtiEXCG ; 
	FmtrNORM_X = FmtrNORM ; 
	FmtrNORM2_X = FmtrNORM2 ; 
	Ftaxpref_X = Ftaxpref ;
	Famtpref_X = Famtpref ;
	Famti_X = Famti ; 
	Famtexempt_X = Famtexempt ; 
	Famtiae_X = Famtiae ;
	Ftamt_X = Ftamt ; 
	FamtiaeEXCG_X = FamtiaeEXCG ; 
	FtamtEXCG_X = FtamtEXCG ;
	CGa_X = CGa ; 
	CGaX_X = CGaX ; 
	CGb_X = CGb ; 
	CGbX_X = CGbX ;
	FtamtALTCG_X = FtamtALTCG ; 
	FtaxCGaX_X = FtaxCGaX ; 
	FtaxCGbX_X = FtaxCGbX ;
	Famt_X = Famt ; 
	Fitemizer_X = Fitemizer ;

	/*********************************************************** 
	Re-do fedtax2 and fedtax3 with switched itemization status 
	************************************************************/
    if Fitemizer_X=1 then do;
		Fitemizer=0 ;
        Fti=FtiNI ;
        %fedtax2 ;
		%fedtax3 ;
    end;
	else if Fitemizer_X=0 then do;
		Fitemizer=1 ;
        Fti=FtiYI;
		%fedtax2 ;
		%fedtax3 ;
	end ;

	/****************************************************************
	Save key variabiles calculated under switched itemization status.
	"SI" at end of variable name indicates it was calculated under
	switched itemization status.
	*****************************************************************/
	FtaxNORMSI = FtaxNORM ; 
	FtaxMAXEISI = FtaxMAXEI ; 
	FtaxALTCGSI = FtaxALTCG ;
	FtaxINCAVGSI = FtaxINCAVG ; 
	FmtrMEISI = FmtrMEI ; 
	Fdtxliab_bcSI = Fdtxliab_bc ; 
	FtaxMINSI = FtaxMIN ; 
	FtiSI = Fti ;
	FtiEXCGSI = FtiEXCG ; 
	FmtrNORMSI = FmtrNORM ; 
	FmtrNORM2SI = FmtrNORM2 ; 
	FtaxprefSI = Ftaxpref ;
	FamtprefSI = Famtpref ;
	FamtiSI = Famti ; 
	FamtexemptSI = Famtexempt ; 
	FamtiaeSI = Famtiae ;
	FtamtSI = Ftamt ; 
	FamtiaeEXCGSI = FamtiaeEXCG ; 
	FtamtEXCGSI = FtamtEXCG ;
	CGaSI = CGa ; 
	CGaXSI = CGaX ; 
	CGbSI = CGb ; 
	CGbXSI = CGbX ;
	FtamtALTCGSI = FtamtALTCG ; 
	FtaxCGaXSI = FtaxCGaX ; 
	FtaxCGbXSI = FtaxCGbX ;
	FamtSI = Famt ; 
	FitemizerSI = Fitemizer ;

	/************************************************************************
	Restore key variabiles to their values under original itemization status.
	*************************************************************************/	
	FtaxNORM = FtaxNORM_X ; 
	FtaxMAXEI = FtaxMAXEI_X ; 
	FtaxALTCG = FtaxALTCG_X ;
	FtaxINCAVG = FtaxINCAVG_X ; 
	FmtrMEI = FmtrMEI_X ; 
	Fdtxliab_bc = Fdtxliab_bc_X ; 
	FtaxMIN = FtaxMIN_X ; 
	Fti = Fti_X ; 
	FmtrNORM = FmtrNORM_X ; 
	FmtrNORM2 = FmtrNORM2_X ; 
	Ftaxpref = Ftaxpref_X ;
	Famtpref = Famtpref_X ;
	Famti = Famti_X ; 
	Famtexempt = Famtexempt_X ; 
	Famtiae = Famtiae_X ;
	Ftamt = Ftamt_X ; 
	FamtiaeEXCG = FamtiaeEXCG_X ; 
	FtamtEXCG = FtamtEXCG_X ;
	CGa = CGa_X ; 
	CGaX = CGaX_X ; 
	CGb = CGb_X ; 
	CGbX = CGbX_X ;
	FtamtALTCG = FtamtALTCG_X ; 
	FtaxCGaX = FtaxCGaX_X ; 
	FtaxCGbX = FtaxCGbX_X ;
	Famt = Famt_X ; 
	Fitemizer = Fitemizer_X ;

end ;
%mend fedtax4 ; 
%fedtax4 ; 



/************************************************************
* FEDTAX5 MACRO												*
* FEDERAL PROVISIONS THAT ONLY APPLY BEFORE 1948            *
* The fedtax5 macro only runs if yearstart < 1948			*
*************************************************************/
%macro fedtax5 ; 

	if fedyear<1948 then do ;
		/* Excluded long-term capital gains */
		if Fseparate=1 then do ;
			Fexltcg1 = (Fcgexpct/100)*ltcg1 ;
			Fexltcg2 = (Fcgexpct/100)*ltcg2 ;
		end ;
		else if Fseparate=2 then do ;
			Fexltcg1 = (Fcgexpct/100)*(ltcg/2) ;
			Fexltcg2 = (Fcgexpct/100)*(ltcg/2) ;
		end ;

		/* AGI for separate filers */
		if filertype="m" and comprop=0 then do ;

			Fagi1 = wagsal1 + businc1 + farminc1 + (ltcg1 - Fexltcg1) 
			+ othcg1 + div1 + int1 + pension1 + rentinc1 + partscorp1 + othinc1
        	-min(Fdivexamt/2,div1)
        	-min(Fdiexamt/2,div1+int1)
        	-othadj1
           	-(1-Fmovexded)*movex1
        	-(1-Fbusexded)*busex1 
			+ Fuiagi*(ui1/max(ui1+ui2,1))
			+ Fssagi*(ssben1/max(ssben1+ssben2,1))
			-(fedyear>=1990)*(1/2)*FsstxliabSE1 ;
			Fagi1 = Fagi1*(1-(Fpctex/100)) ;

			Fagi2 = wagsal2 + businc2 + farminc2 + (ltcg2 - Fexltcg2) 
			+ othcg2 + div2 + int2 + pension2 + rentinc2 + partscorp2 + othinc2
        	-min(Fdivexamt/2,div2)
        	-min(Fdiexamt/2,div2+int2)
        	-othadj2
           	-(1-Fmovexded)*movex2
        	-(1-Fbusexded)*busex2 
			+ Fuiagi*(ui2/max(ui1+ui2,1))
			+ Fssagi*(ssben2/max(ssben1+ssben2,1))
			-(fedyear>=1990)*(1/2)*FsstxliabSE1 ;
			Fagi2 = Fagi2*(1-(Fpctex/100)) ;

		end ;

		else if filertype="m" and comprop=1 then do ;
			Fagi1 = (Fagi/2)*(1-(Fpctex/100)) ;
			Fagi2 = (Fagi/2)*(1-(Fpctex/100)) ;
		end ;

        /************************************************************
        * Federal taxable income for each spouse filing separately  *
        * (only relevant pre-1948).                                 *
        *************************************************************/
        /* non-community-property states, pre-1948 */
        if Fseparate=1 then do;
			Fstded1 = min(Fmaxstded,max(0,(Fpctstded/100)*max(Fagi1,0))) ;
			Fstded2 = min(Fmaxstded,max(0,(Fpctstded/100)*max(Fagi2,0))) ;	
			if Fitemded >= (Fstded1+Fstded2) then FitemizerSEP=1 ;
				else FitemizerSEP=0 ;
			/* non-discretionary deductions */
			if Fagi1>=Fagi2 then do ;
				FexemptND1 = Fexpercap + deps*(Fexpercap + Fex_dep) ;
				FexemptND2 = Fexpercap ;
			end ;
			else do ;
				FexemptND1 = Fexpercap ;
				FexemptND2 = Fexpercap + deps*(Fexpercap + Fex_dep) ;
			end ;
			if Ssepfiler=1 then do;
				Fsit1=taxs1 ;
				Fsit2=taxs2 ;
			end;
			else if separate=1 and statename ne "zz" then do ;
				Fsit1 = taxs*(max(taxs1,0)/max(1,max(taxs1,0)+max(taxs2,0))) ;
				Fsit2 = taxs*(max(taxs2,0)/max(1,max(taxs1,0)+max(taxs2,0))) ;
			end ;
			else if statename ne "zz" then do ;
				Fsit1 = taxs*(max(Fagi1,0)/max(1,max(Fagi1,0)+max(Fagi2,0))) ;
				Fsit2 = taxs*(max(Fagi2,0)/max(1,max(Fagi1,0)+max(Fagi2,0))) ;
			end ;
			else do ;
				Fsit1=stinctax*(max(Fagi1,0)/max(1,max(Fagi1,0)+max(Fagi2,0))) ;
				Fsit2=stinctax*(max(Fagi2,0)/max(1,max(Fagi1,0)+max(Fagi2,0))) ;
			end ;
			FdeductionsND1 = FexemptND1 + FitemizerSEP*max(Fsit1,Fstded1)
				+ (1-FitemizerSEP)*Fstded1 ;
			FdeductionsND2 = FexemptND2 + FitemizerSEP*max(Fsit2,Fstded2) 
				+ (1-FitemizerSEP)*Fstded2 ;
			FtiND1 = max(0, Fagi1-FdeductionsND1) ;
			FtiND2 = max(0, Fagi2-FdeductionsND2) ;
			/* Discretionary deductions */
			/* Note: each spouse is here assumed to deduct at least the standard deduction, to avoid notches */
			FdeductionsDISC = Fexreturn + FitemizerSEP*max(0,Fitemded-max(Fsit1,Fstded1)-max(Fsit2,Fstded2)) ;
			if FtiND1>=FtiND2 then do ;
				FdedDISC1=min(FdeductionsDISC,FtiND1-FtiND2);
				FdedDISC2=0 ;
				FdedSPLIT=max(0,FdeductionsDISC-FdedDISC1)/2 ;
			end ;
			else do ;
				FdedDISC1=0 ;
				FdedDISC2=min(FdeductionsDISC,FtiND2-FtiND1);
				FdedSPLIT=max(0,FdeductionsDISC-FdedDISC2)/2 ;
			end ;
			FexDISC1 = Fexreturn*((FdedDISC1+FdedSPLIT)/max(FdedDISC1+FdedDISC2+FdedSPLIT*2,1)) ;
			FexDISC2 = Fexreturn*((FdedDISC2+FdedSPLIT)/max(FdedDISC1+FdedDISC2+FdedSPLIT*2,1)) ;
			Fexempt1 = FexemptND1 + FexDISC1 ;
			Fexempt2 = FexemptND2 + FexDISC2 ;
			Fti1 = max(0, FtiND1 - FdedDISC1 - FdedSPLIT) ;
			Fti2 = max(0, FtiND2 - FdedDISC2 - FdedSPLIT) ;
		end;
        /* community property states, pre-1948 */
        else if Fseparate=2 then do;
			Fstded1 = min(Fmaxstded,max(0,(Fpctstded/100)*max(Fagi1,0))) ;
			Fstded2 = min(Fmaxstded,max(0,(Fpctstded/100)*max(Fagi2,0))) ;	
			if Fitemded >= (Fstded1+Fstded2) then FitemizerSEP=1 ;
				else FitemizerSEP=0 ;
			/* division of exemptions */
			if Fagi1>=Fagi2 then do ;
				FexemptND1 = Fexpercap + deps*(Fexpercap + Fex_dep) ;
				FexemptND2 = Fexpercap ;
				FexemptDISC1 = 0 ;
				FexemptDISC2 = min(Fexreturn, FexemptND1-FexemptND2) ;
				FexemptSPLIT = max(0, Fexreturn-FexemptDISC2)/2 ;
			end ;
			else do ;
				FexemptND1 = Fexpercap ;
				FexemptND2 = Fexpercap + deps*(Fexpercap + Fex_dep) ;
				FexemptDISC1 = min(Fexreturn, FexemptND2-FexemptND1) ;
				FexemptDISC2 = 0 ; 
				FexemptSPLIT = max(0, Fexreturn-FexemptDISC1)/2 ;
			end ;
			Fexempt1 = FexemptND1 + FexemptDISC1 + FexemptSPLIT ;
			Fexempt2 = FexemptND2 + FexemptDISC2 + FexemptSPLIT ; 
			Fti1 = max(0, Fagi1 - FitemizerSEP*(Fitemded/2) - (1-FitemizerSEP)*Fstded1 
				- FexemptND1 - FexemptDISC1 - FexemptSPLIT) ;
			Fti2 = max(0, Fagi2 - FitemizerSEP*(Fitemded/2) - (1-FitemizerSEP)*Fstded2 
				- FexemptND2 - FexemptDISC2 - FexemptSPLIT) ;
        end;

        /**************************************************************************
        *   "Normal" federal tax calculation for separate filers                  *
		***************************************************************************/   		
        if Fseparate>0 then do;
               %bracketreader(Fti1, FtaxNORM1, Frate, Fbracket, Fbracknum) ;
               FmtrNORM1=brackmtr ;
               %bracketreader(Fti2, FtaxNORM2, Frate, Fbracket, Fbracknum) ;
               FmtrNORM2=brackmtr ;
        end;

		/***************************************************************
		* 1917 federal excess profits tax  							   *
		****************************************************************/
		if fedyear=1917 then do ;
			if labinc>=6000 then do ;
				FtaxNORM = FtaxNORM + .08*max(0,labinc-6000) ;
				FmtrNORM = FmtrNORM + 8 ;
			end; 
			if Fseparate=1 then do ;
				if labinc1>=6000 then do ;
					FtaxNORM1 = FtaxNORM1 + .08*max(0,labinc1-6000) ;
					FmtrNORM1 = FmtrNORM1 + 8 ;
				end ;
				if labinc2>=6000 then do ;
					FtaxNORM2 = FtaxNORM2 + .08*max(0,labinc2-6000) ;
					FmtrNORM2 = FmtrNORM2 + 8 ;
				end ;
			end ;
			else if Fseparate=2 and (labinc/2)>=6000 then do ;
				FtaxNORM1 = FtaxNORM1 + .08*max((labinc/2)-6000,0) ;
				FtaxNORM2 = FtaxNORM2 + .08*max((labinc/2)-6000,0) ;
				FmtrNORM1 = FmtrNORM1 + 8 ;
				FmtrNORM2 = FmtrNORM2 + 8 ;
			end;
		end;


        /***************************************************************
        *                      "Extra" tax                             *
        *             		Applicable 1913-45                         *
        *    From 1913-45, what is coded below was actually called the *
        *    "normal tax" and what gets calculated above was called    *
        *    the "surtax," but I reversed them to economize on size of *
        *    bracket and rate arrays. Fxtax = additional tax liability *
        *    under this tax.								           *
        *    Fxtax = tax liability from "extra" tax.                   *
        ****************************************************************/
        if Fxtaxtype="paratax" then do;
				/********************************************************
				* Earned income credit, 1934-1943 						*
				*********************************************************/ 
				if fedyear<1944 and fedyear>1933 then do ;
					/* single or joint */
						FNI=max(0,Fti+Fexempt) ;
						if FNI<3000 then FENI = FNI ;
						else FENI=min(14000,max(3000,labinc-busex
							-min(1,labinc/max(Fagi,1))*(taxs + (statename="zz")*stinctax)));
						FoldEIcredit = .1*min(FENI,FNI) ;
					/* married filing separately, non-community property state */
					if Fseparate = 1 then do ; 
						FNI1=max(0,Fti1 + Fexempt1) ;
						FNI2=max(0,Fti2 + Fexempt2) ;
						if FNI1<3000 then FENI1 = FNI1 ;
						else FENI1=min(14000,max(3000,labinc1-busex1
							-min(1,labinc1/max(Fagi,1))*(taxs + (statename="zz")*stinctax)));
						if FNI2<3000 then FENI2 = FNI2 ;
						else FENI2=min(14000,max(3000,labinc2-busex2
							-min(1,labinc2/max(Fagi,1))*(taxs + (statename="zz")*stinctax)));
						FoldEIcredit1 = .1*min(FENI1,FNI1) ;
						FoldEIcredit2 = .1*min(FENI2,FNI2) ;
					end ;
					/* married filing separately, community-property state */					
					else if Fseparate = 2 then do ;
						FNI1=max(0,Fti1 + Fexempt1) ;
						FNI2=max(0,Fti2 + Fexempt2) ;
						if FNI1<3000 then FENI1 = FNI1 ;
						else FENI1=min(14000,max(3000,(labinc-busex
							-min(1,labinc/max(Fagi,1))*(taxs + (statename="zz")*stinctax))/2));
						if FNI2<3000 then FENI2 = FNI2 ;
						else FENI2=min(14000,max(3000,(labinc-busex
							-min(1,labinc/max(Fagi,1))*(taxs + (statename="zz")*stinctax))/2)) ;
						FoldEIcredit1 = .1*min(FENI1,FNI1) ;
						FoldEIcredit2 = .1*min(FENI2,FNI2) ;
					end ;
				end ;
				else do ;
					FoldEIcredit=0 ;
					FoldEIcredit1=0 ;
					FoldEIcredit2=0 ;
				end ;

				/* adjusted gross income for "normal" (extra) tax, 1913-45 */
                Fxagi=max(0,
                lab+othcg+int+pension+rentinc+partscorp+othinc
                +(1-(Fxcgexpct/100))*ltcg
                +(1-(Fxdivexpct/100))*div
                -(1-Fmovexded)*movex
                -(1-Fbusexded)*busex)*(1-(Fxpctex/100)) ;

				if Fseparate=1 then do ;
					Fxagi1 = max(0, wagsal1 + businc1 + farminc1 + (ltcg1 - Fexltcg1) 
					+ othcg1 + int1 + pension1 + rentinc1 + partscorp1 + othinc1
		        	+(1-(Fxcgexpct/100))*ltcg1
					+(1-(Fxdivexpct/100))*div1
 		          	-(1-Fmovexded)*movex1
		        	-(1-Fbusexded)*busex1)*(1-(Fxpctex/100)) ;

					Fxagi2 = max(0, wagsal2 + businc2 + farminc2 + (ltcg2 - Fexltcg2) 
					+ othcg2 + int2 + pension2 + rentinc2 + partscorp2 + othinc2
		        	+(1-(Fxcgexpct/100))*ltcg2
					+(1-(Fxdivexpct/100))*div2
 		          	-(1-Fmovexded)*movex2
		        	-(1-Fbusexded)*busex2)*(1-(Fxpctex/100)) ;
				end ;
				else if Fseparate=2 then do ;
					Fxagi1 = Fxagi/2 ;
					Fxagi2 = Fxagi/2 ;
				end ;


				/* Taxable income for "normal" extra tax 1913-1945 */
				/* single return */
				if filertype="s" or filertype="h" then do ;
					Fxti = max(0,Fxagi
                	-max(Fxintded*Fitemded, Fstded)
                	-(Fxexreturn + Fxex_dep*deps)
					- FoldEIcredit);
					Fxexempt = Fxexreturn + Fxex_dep*deps ;
				end ;

				/* joint return */
				else if filertype="m" then do ;
					if (fedyear=1944 or fedyear=1945) then F2ndSpouseEx=1 ;
						else F2ndSpouseEx=0 ;
					Fxti = max(0,Fxagi
	   	            -max(Fxintded*Fitemded, Fstded)
	                -(Fxexreturn + Fxex_dep*deps)
					- FoldEIcredit 
					- F2ndSpouseEx*max(0,min(Fxagi2,500)));
					Fxexempt = Fxexreturn + Fxex_dep*deps ;
				end ;

		        /* married filing separately, non-community-property states, pre-1948 */
		        if Fseparate=1 then do;
					/* non-discretionary deductions */
					if Fxagi1>=Fxagi2 then do ;
						FxexemptND1 = deps*Fxex_dep ;
						FxexemptND2 = 0 ;
					end ;
					else do ;
						FxexemptND1 = 0 ;
						FxexemptND2 = deps*Fxex_dep ;
					end ;
					FxdeductionsND1 = FxexemptND1 + FitemizerSEP*Fsit1
						+ (1-FitemizerSEP)*Fstded1 ;
					FxdeductionsND2 = FxexemptND2 + FitemizerSEP*Fsit2 
						+ (1-FitemizerSEP)*Fstded2 ;
					FxtiND1 = max(0, Fxagi1-FxdeductionsND1-FoldEIcredit1) ;
					FxtiND2 = max(0, Fxagi2-FxdeductionsND2-FoldEIcredit2) ;
					FxdeductionsDISC = Fxexreturn + FitemizerSEP*max(0,Fitemded-Fsit1-Fsit2) ;
					if FxtiND1>=FxtiND2 then do ;
						FxdedDISC1=min(FxdeductionsDISC,FxtiND1-FxtiND2);
						FxdedDISC2=0 ;
						FxdedSPLIT=max(0,FxdeductionsDISC-FxdedDISC1)/2 ;
					end ;
					else do ;
						FxdedDISC1=0 ;
						FxdedDISC2=min(FxdeductionsDISC,FxtiND2-FxtiND1);
						FxdedSPLIT=max(0,FxdeductionsDISC-FxdedDISC2)/2 ;
					end ;
					FxexemptDISC1 = Fxexreturn*((FxdedDISC1+FxdedSPLIT)/
						max(1,FxdedDISC1+FxdedDISC2+2*FxdedSPLIT)) ;
					FxexemptDISC2 = Fxexreturn*((FxdedDISC2+FxdedSPLIT)/
						max(1,FxdedDISC1+FxdedDISC2+2*FxdedSPLIT)) ;
					Fxexempt1 = FxexemptND1+FxexemptDISC1 ;
					Fxexempt2 = FxexemptND2+FxexemptDISC2 ;
					Fxti1 = max(0, FxtiND1 - FxdedDISC1 - FxdedSPLIT) ;
					Fxti2 = max(0, FxtiND2 - FxdedDISC2 - FxdedSPLIT) ;
				end;
		        /* married filing separately, community property states, pre-1948 */
		        else if Fseparate=2 then do;
					/* division of exemptions */
					if Fxagi1>=Fxagi2 then do ;
						FxexemptND1 = deps*Fxex_dep ;
						FxexemptND2 = 0 ;
						FxexemptDISC1 = 0 ;
						FxexemptDISC2 = min(Fxexreturn, FxexemptND1-FxexemptND2) ;
						FxexemptSPLIT = max(0, Fxexreturn-FxexemptDISC2)/2 ;
					end ;
					else do ;
						FxexemptND1 = 0 ;
						FxexemptND2 = deps*Fxex_dep ;
						FxexemptDISC1 = min(Fxexreturn, FxexemptND2-FxexemptND1) ;
						FxexemptDISC2 = 0 ; 
						FxexemptSPLIT = max(0, Fxexreturn-FxexemptDISC1)/2 ;
					end ;
					Fxexempt1 = FxexemptND1 + FxexemptDISC1 ;
					Fxexempt2 = FxexemptND2 + FxexemptDISC2 ; 
					Fxti1 = max(0, Fxagi1 - FitemizerSEP*(Fitemded/2) - (1-FitemizerSEP)*Fstded1 
						- FxexemptND1 - FxexemptDISC1 - FxexemptSPLIT - FoldEIcredit1) ;
					Fxti2 = max(0, Fxagi2 - FitemizerSEP*(Fitemded/2) - (1-FitemizerSEP)*Fstded2 
						- FxexemptND2 - FxexemptDISC2 - FxexemptSPLIT - FoldEIcredit2) ;
	 	       end;

				/* calculate "normal" (extra) tax, 1913-45 */
                /* Single or joint filers */
                    %bracketreader(Fxti, Fxtax, Fxrate, Fxbracket, Fxbracknum) ;
                    Fxtax = max(0, Fxtax - Fxcred_dep*deps) ;
                    FtaxNORM = FtaxNORM + Fxtax ;
                    FmtrNORM=FmtrNORM+brackmtr ;
				/* separate filers */
                if Fseparate>0 then do;
                        %bracketreader(Fxti1, Fxtax1, Fxrate, Fxbracket, Fxbracknum) ;
                                FmtrNORM1=FmtrNORM1+brackmtr;
						%bracketreader(Fxti2, Fxtax2, Fxrate, Fxbracket, Fxbracknum) ;
                                FmtrNORM2=FmtrNORM2+brackmtr;
                        FtaxNORM1=FtaxNORM1+Fxtax1;
                        FtaxNORM2=FtaxNORM2+Fxtax2;
                end;
        end;

		/************************************************************************************
		*  Earned income credit, 1924-31													*
		*************************************************************************************/
		if fedyear<1932 and fedyear>1923 then do ;

			/* Net income */
			/* single or joint */
			FNI=max(0,Fti) ;
			/* married filing separately*/
			if Fseparate > 0 then do ;
				FNI1=max(0,Fti1) ;
				FNI2=max(0,Fti2) ; 
			end ;
	
			/* Earned net income */
			/* single or joint */
			if fedyear=1924 then do ;
				if FNI<5000 then FENI = FNI ;
				else FENI=min(10000,max(5000,labinc)); 
			end ;
			else if fedyear<1928 and fedyear>1924 then do ;
				if FNI<5000 then FENI = FNI ;
				else FENI=min(20000,max(5000,labinc));
			end ;
			else if fedyear<1932 and fedyear>1927 then do ;
				if FNI<5000 then FENI = FNI ;
				else FENI=min(30000,max(5000,labinc));
			end ;					
			/* married, non-community property state */
			if Fseparate = 1 then do ;
				if fedyear=1924 then do ;
					if FNI1<5000 then FENI1 = FNI1 ;
					else FENI1=min(10000,max(5000,labinc1));
					if FNI2<5000 then FENI2 = FNI2 ;
					else FENI2=min(10000,max(5000,labinc2));
				end ;
				else if fedyear<1928 and fedyear>1924 then do ;
					if FNI1<5000 then FENI1 = FNI1 ;
					else FENI1=min(20000,max(5000,labinc1));
					if FNI2<5000 then FENI2 = FNI2 ;
					else FENI2=min(20000,max(5000,labinc2));
				end ;
				else if fedyear<1932 and fedyear>1927 then do ;
					if FNI1<5000 then FENI1 = FNI1 ;
					else FENI1=min(30000,max(5000,labinc1));
					if FNI2<5000 then FENI2 = FNI2 ;
					else FENI2=min(30000,max(5000,labinc2));
				end ;					
			end ;
			/* married, community-property state */					
			else if Fseparate = 2 then do ;
				if fedyear=1924 then do ;
					if FNI1<5000 then FENI1 = FNI1 ;
					else FENI1=min(10000,max(5000,labinc/2));
 					if FNI2<5000 then FENI2 = FNI2 ;
					else FENI2=min(10000,max(5000,labinc/2));
				end ;
				else if fedyear<1928 and fedyear>1924 then do ;
					if FNI1<5000 then FENI1 = FNI1 ;
					else FENI1=min(20000,max(5000,labinc/2));
					if FNI2<5000 then FENI2 = FNI2 ;
					else FENI2=min(20000,max(5000,labinc/2));
				end ;
				else if fedyear<1932 and fedyear>1927 then do ;
					if FNI1<5000 then FENI1 = FNI1 ;
					else FENI1=min(30000,max(5000,labinc/2));
					if FNI2<5000 then FENI2 = FNI2 ;
					else FENI2=min(30000,max(5000,labinc/2));
				end ;					
			end ;

			/* Calculate federal earned income credit and subtract from tax liability 1924-31 */
			/* 1924 */
			if fedyear=1924 then do ;

				/* single or joint */
	            FoldEICti = max(0, min(FENI-Fxexempt,FNI-Fxexempt)) ;
        	    %bracketreader(FoldEICti, FoldEICbase, Fxrate, Fxbracket, Fxbracknum) ;
	            FtaxNORM = max(0, FtaxNORM - .25*FoldEICbase) ;
	            

				/* married filing separately */
	            if Fseparate>0 then do;
					FoldEICti1 = max(0, min(FENI1-Fxexempt1,FNI1-Fxexempt1)) ;
					FoldEICti2 = max(0, min(FENI2-Fxexempt2,FNI2-Fxexempt2)) ;

       		        %bracketreader(FoldEICti1, FoldEICbase1, Fxrate, Fxbracket, Fxbracknum) ;
	       	        FtaxNORM1 = max(0, FtaxNORM1 - .25*FoldEICbase1) ;
	       	        %bracketreader(FoldEICti2, FoldEICbase2, Fxrate, Fxbracket, Fxbracknum) ;
	       	        FtaxNORM2 = max(0, FtaxNORM2 - .25*FoldEICbase2) ;
				end ;

			end ;

			else if fedyear<1932 and fedyear>1924 then do ;

				/* single or joint */
				FoldEICti = max(0, FENI) ;
				FoldEICtix = max(0, min(FENI-Fxexempt,FNI-Fxexempt)) ;
        	    %bracketreader(FoldEICti, FoldEICbase, Frate, Fbracket, Fbracknum) ;
        	    %bracketreader(FoldEICtix, FoldEICbasex, Fxrate, Fxbracket, Fxbracknum) ;
	            FtaxNORM = max(0, FtaxNORM - .25*(FoldEICbase+FoldEICbasex)) ;

				/* married filing separately */
	            if Fseparate>0 then do;
					FoldEICti1 = max(0, FENI1) ;
					FoldEICti2 = max(0, FENI2) ;
					FoldEICti1x = max(0, min(FENI1-Fxexempt1,FNI1-Fxexempt1)) ;
					FoldEICti2x = max(0, min(FENI2-Fxexempt2,FNI2-Fxexempt2)) ;
					
       		        %bracketreader(FoldEICti1, FoldEICbase1, Frate, Fbracket, Fbracknum) ;
       		        %bracketreader(FoldEICti1x, FoldEICbase1x, Fxrate, Fxbracket, Fxbracknum) ;
	       	        FtaxNORM1 = max(0, FtaxNORM1 - .25*(FoldEICbase1+FoldEICbase1x)) ;

       		        %bracketreader(FoldEICti2, FoldEICbase2, Frate, Fbracket, Fbracknum) ;
       		        %bracketreader(FoldEICti2x, FoldEICbase2x, Fxrate, Fxbracket, Fxbracknum) ;
	       	        FtaxNORM2 = max(0, FtaxNORM2 - .25*(FoldEICbase2+FoldEICbase2x)) ;
				end ;
			end ;
		end ;


        /**************************************************************************
        *    Alternative capital gains tax calculation in federal tax before 1948 *
        ***************************************************************************
        **************************************************************************
        *    cgmax1, (1922-33, 1938-47)                                          *
        *    Re-calculate normal tax and any surtax excluding gains, tax gains   *
		*	 separately at a flat rate.      									 *
		*    Same feature also applies 1948-69, calculated later below.
        **************************************************************************/
        if Fsptx="cgmax1" and Fedyear<1948 and ltcg ne 0 and
			  ((FmtrNORM *(1-(Fcgexpct/100)) >  Fsptxrate) 
			or (FmtrNORM1*(1-(Fcgexpct/100)) >  Fsptxrate) 
			or (FmtrNORM2*(1-(Fcgexpct/100)) >  Fsptxrate))
			then do;
				/********************************************************
				* Re-calculate taxable income, excluding capital  		*
				* gains													*
				*********************************************************/
				/* single, HoH, or joint */
                FtiEXCG = max(0, Fti - (1-(Fcgexpct/100))*ltcg);

				/* married filing separately */
				if Fseparate=1 then do ;
 					if FmtrNORM1*(1-(Fcgexpct/100)) >  Fsptxrate then
						FtiND1excg = max(0, Fagi1-(1-(Fcgexpct/100))*ltcg1 - FdeductionsND1) ;
					else FtiND1excg = FtiND1 ;
					if FmtrNORM2*(1-(Fcgexpct/100)) >  Fsptxrate then
						FtiND2excg = max(0, Fagi2-(1-(Fcgexpct/100))*ltcg2 -FdeductionsND2) ;
					else FtiND2excg = FtiND2 ;
					if FtiND1excg>=FtiND2excg then do ;
						FdedDISC1excg=min(FdeductionsDISC,FtiND1excg-FtiND2excg);
						FdedDISC2excg=0 ;
						FdedSPLITexcg=max(0,FdeductionsDISC-FdedDISC1excg)/2 ;
					end ;
					else do ;
						FdedDISC1excg=0 ;
						FdedDISC2excg=min(FdeductionsDISC,FtiND2excg-FtiND1excg);
						FdedSPLITexcg=max(0,FdeductionsDISC-FdedDISC2excg)/2 ;
					end ;
					FexDISC1excg = Fexreturn*((FdedDISC1excg+FdedSPLITexcg)/
						max(FdedDISC1excg+FdedDISC2excg+FdedSPLITexcg,1)) ;
					FexDISC2excg = Fexreturn*((FdedDISC2excg+FdedSPLITexcg)/
						max(FdedDISC1excg+FdedDISC2excg+FdedSPLITexcg,1)) ;
					Fexempt1excg = FexemptND1 + FexDISC1excg ;
					Fexempt2excg = FexemptND2 + FexDISC2excg ;
					FtiEXCG1 = max(0, FtiND1excg - FdedDISC1excg - FdedSPLITexcg) ;
					FtiEXCG2 = max(0, FtiND2excg - FdedDISC2excg - FdedSPLITexcg) ;	
				end ;
				else if Fseparate=2 then do ;
					Fexempt1excg = Fexempt1 ;
					Fexempt2excg = Fexempt2 ;
					if FmtrNORM1*(1-(Fcgexpct/100)) >  Fsptxrate then
						FtiEXCG1 = max(0, Fti1-(1-(Fcgexpct/100))*(ltcg/2)) ; 
					else FtiEXCG1 = Fti1 ;
					if FmtrNORM2*(1-(Fcgexpct/100)) >  Fsptxrate then
						FtiEXCG2 = max(0, Fti2-(1-(Fcgexpct/100))*(ltcg/2)) ;
 					else FtiEXCG2 = Fti2 ;
				end ;

				/********************************************************
				* Re-calculate earned income credit, excluding capital  *
				* gains, 1938-1943										*
				*********************************************************/ 
				if fedyear<1944 and fedyear>1937 then do ;
					/* single or joint */
					FNI=max(0,Fti+Fexempt-(1-(Fcgexpct/100))*ltcg) ;
					if FNI<3000 then FENI = FNI ;
					else FENI=min(14000,max(3000,labinc-busex
						-min(1,labinc/max(Fagi,1))*(taxs + (statename="zz")*stinctax)));
					FoldEIcredit = .1*min(FENI,FNI) ;

					/* married, non-community property state */
					if Fseparate = 1 then do ; 
						FNI1=max(0,FtiEXCG1+Fexempt1excg) ;
						FNI2=max(0,FtiEXCG2+Fexempt2excg) ;
						if FNI1<3000 then FENI1 = FNI1 ;
						else FENI1=min(14000,max(3000,labinc1-busex1
							-min(1,labinc1/max(Fagi,1))*(taxs + (statename="zz")*stinctax)));
						if FNI2<3000 then FENI2 = FNI2 ;
						else FENI2=min(14000,max(3000,labinc2-busex2
							-min(1,labinc2/max(Fagi,1))*(taxs + (statename="zz")*stinctax)));
						FoldEIcredit1 = .1*min(FENI1,FNI1) ;
						FoldEIcredit2 = .1*min(FENI2,FNI2) ;
					end ;
					/* married, community-property state */					
					else if Fseparate = 2 then do ;
						FNI1=max(0,FtiEXCG1+Fexempt1) ;
						FNI2=max(0,FtiEXCG2+Fexempt2) ;
						if FNI1<3000 then FENI1 = FNI1 ;
						else FENI1=min(14000,max(3000,(labinc-busex
							-min(1,labinc/max(Fagi,1))*(taxs + (statename="zz")*stinctax))/2));
						if FNI2<3000 then FENI2 = FNI2 ;
						else FENI2=min(14000,max(3000,(labinc-busex
							-min(1,labinc/max(Fagi,1))*(taxs + (statename="zz")*stinctax))/2)) ;
						FoldEIcredit1 = .1*min(FENI1,FNI1) ;
						FoldEIcredit2 = .1*min(FENI2,FNI2) ;
					end ;
				end ;
				else do ;
					FoldEIcredit=0 ;
					FoldEIcredit1=0 ;
					FoldEIcredit2=0 ;
				end ;

				/*********************************************************
				* Re-calculate taxable income for "normal" (extra) tax   * 
				* 1913-1945, under alternative capital gains computation *
				**********************************************************/
				if fedyear<1946 then do ;
					/* single return */
					if filertype="s" or filertype="h" then do ;
						FxtiEXCG = max(0,Fxagi
                		-max(Fxintded*Fitemded, Fstded)
                		-(Fxexreturn + Fxex_dep*deps)
						- FoldEIcredit - (1-(Fxcgexpct/100))*ltcg);
					end ;

					/* joint return */
					else if filertype="m" then do ;
						if (fedyear=1944 or fedyear=1945) then F2ndSpouseEx=1 ;
							else F2ndSpouseEx=0 ;
						FxtiEXCG = max(0,Fxagi
	   	            	-max(Fxintded*Fitemded, Fstded)
	                	-(Fxexreturn + Fxex_dep*deps)
						- FoldEIcredit 
						- F2ndSpouseEx*max(0,min(Fxagi2,500))
						- (1-(Fxcgexpct/100))*ltcg);
					end ;

		        	/* married filing separately, non-community-property states */
		        	if Fseparate=1 then do;
						/* non-discretionary deductions */
 						if (FmtrNORM1*(1-(Fxcgexpct/100)) >  Fsptxrate) then
							FxtiND1excg = max(0, Fxagi1-(1-(Fxcgexpct/100))*ltcg1-FxdeductionsND1-FoldEIcredit1) ;
						else FxtiND1excg = FxtiND1 ;
						if (FmtrNORM2*(1-(Fxcgexpct/100)) >  Fsptxrate) then
							FxtiND2excg = max(0, Fxagi2-(1-(Fxcgexpct/100))*ltcg2-FxdeductionsND2-FoldEIcredit2) ;
						else FxtiND2excg = FxtiND2 ;
						if FxtiND1excg>=FxtiND2excg then do ;
							FxdedDISC1excg=min(FxdeductionsDISC,FxtiND1excg-FxtiND2excg);
							FxdedDISC2excg=0 ;
							FxdedSPLITexcg=max(0,FxdeductionsDISC-FxdedDISC1excg)/2 ;
						end ;
						else do ;
							FxdedDISC1excg=0 ;
							FxdedDISC2excg=min(FxdeductionsDISC,FxtiND2excg-FxtiND1excg);
							FxdedSPLITexcg=max(0,FxdeductionsDISC-FxdedDISC2excg)/2 ;
						end ;	
							FxexemptDISC1excg = Fxexreturn*
								((FxdedDISC1excg+FxdedSPLITexcg)/max(1,FxdedDISC1excg+FxdedDISC2excg+2*FxdedSPLITexcg)) ;
							FxexemptDISC2excg = Fxexreturn*
								((FxdedDISC2excg+FxdedSPLITexcg)/max(1,FxdedDISC1excg+FxdedDISC2excg+2*FxdedSPLITexcg)) ;
							Fxexempt1excg = FxexemptND1+FxexemptDISC1 ;
							Fxexempt2excg = FxexemptND2+FxexemptDISC2 ;
							FxtiEXCG1 = max(0, FxtiND1excg - FxdedDISC1excg - FxdedSPLITexcg) ;
							FxtiEXCG2 = max(0, FxtiND2excg - FxdedDISC2excg - FxdedSPLITexcg) ;
					end;
		        	/* married filing separately, community property states */
		        	else if Fseparate=2 then do;
						Fxexempt1excg = Fxexempt1 ;
						Fxexempt2excg = Fxexempt2 ;
 						if (FmtrNORM1*(1-(Fxcgexpct/100)) >  Fsptxrate) then
							FxtiEXCG1 = Fxti1 - (1-(Fxcgexpct/100))*(ltcg/2) ;
						else FxtiEXCG1 = Fxti1 ;
 						if (FmtrNORM2*(1-(Fxcgexpct/100)) >  Fsptxrate) then
							FxtiEXCG2 = max(0, Fxti2 - (1-(Fxcgexpct/100))*(ltcg/2)) ;
						else FxtiEXCG2 = Fxti2 ;
	 	       		end;
				end ;
				else do ;
					FxtiEXCG=0 ;
					FxtiEXCG1=0 ;
					FxtiEXCG2=0 ;
				end ;

				/******************************************************
				* Calculate alternative capital gains tax liability   *
				*******************************************************/

                /* single, HoH, or joint */
                %bracketreader(FtiEXCG, FtaxEXCG, Frate, Fbracket, Fbracknum) ;
                FtaxALTCG = FtaxEXCG + (Fsptxrate/100)*ltcg;
                /* application of alt. cap gains tax to pre-1946 "normal" tax */
                if Fxtaxtype="paratax" then do;
                    %bracketreader(FxtiEXCG, FxtaxEXCG, Fxrate, Fxbracket, Fxbracknum) ;
                    FtaxALTCG = FtaxALTCG + FxtaxEXCG ;
                end;
                
                /* married filing separately */
                if Fseparate>0 then do;
                	if FmtrNORM1*(1-(Fcgexpct/100))>Fsptxrate then do;
                    	%bracketreader(FtiEXCG1, FtaxEXCG1, Frate, Fbracket, Fbracknum) ;
						if Fseparate=1 then FtaxCG1=(Fsptxrate/100)*ltcg1 ;
                        else if Fseparate=2 then FtaxCG1=(Fsptxrate/100)*(ltcg/2) ;
						FtaxALTCG1 = FtaxEXCG1 + FtaxCG1 ;
                    end;
                    else do;
                    	FtaxEXCG1=FtaxNORM1;
                        FtaxCG1=0;
						FtaxALTCG1 = FtaxEXCG1+FtaxNORM1;
                    end;
                    if FmtrNORM2*(1-(Fcgexpct/100))>Fsptxrate then do;
                    	%bracketreader(FtiEXCG2, FtaxEXCG2, Frate, Fbracket, Fbracknum) ;
						if Fseparate=1 then FtaxCG2=(Fsptxrate/100)*ltcg2 ;
                        else if Fseparate=2 then FtaxCG2=(Fsptxrate/100)*(ltcg/2) ;
						FtaxALTCG2 = FtaxEXCG2+FtaxCG2 ;
                    end;
                    else do;
                    	FtaxEXCG2=FtaxNORM2;
                        FtaxCG2=0;
						FtaxALTCG2 = FtaxEXCG2+FtaxCG2 ;
                    end;
                    /* application of alt. cap gains tax to pre-1946 extra tax */
                    if Fxtaxtype="paratax" then do;
                    	if FtaxCG1>0 then do;
                        	%bracketreader(FxtiEXCG1, FxtaxEXCG1, Fxrate, Fxbracket, Fxbracknum) ;
                        	FtaxALTCG1 = FtaxALTCG1 + FxtaxEXCG1 ;
                    	end;
                    	else FtaxALTCG1 = FtaxALTCG1 + Fxtax1 ;
                    	if FtaxCG2>0 then do;
                        	%bracketreader(FxtiEXCG2, FxtaxEXCG2, Fxrate, Fxbracket, Fxbracknum) ;
                        	FtaxALTCG2 = FtaxALTCG2 + FxtaxEXCG2 ;
                    	end;
                    	else FtaxALTCG2 = FtaxALTCG2 + Fxtax2 ;
                	end;
            	end;
        

			/************************************************************************************
			*  Re-calculate earned income credit under alternative capital gains computation,   *
			*  1924-31																			*
			*************************************************************************************/
			if fedyear<1932 and fedyear>1923 then do ;

				/* Net income */
				/* single or joint */
				FNI=max(0,Fti-(1-(Fcgexpct/100))*ltcg) ;

				/* married filing separately*/
				if Fseparate > 0 then do ;
					FNI1=max(0,FtiEXCG1) ;
					FNI2=max(0,FtiEXCG2) ;
				end ;

				/* Earned net income */
				/* single, HoH, or joint */
				if fedyear=1924 then do ;
					if FNI<5000 then FENI = FNI ;
					else FENI=min(10000,max(5000,labinc)); 
				end ;
				else if fedyear<1928 and fedyear>1924 then do ;
					if FNI<5000 then FENI = FNI ;
					else FENI=min(20000,max(5000,labinc));
				end ;
				else if fedyear<1932 and fedyear>1927 then do ;
					if FNI<5000 then FENI = FNI ;
					else FENI=min(30000,max(5000,labinc));
				end ;					

				/* married, non-community property state */
				if Fseparate = 1 then do ;
					if fedyear=1924 then do ;
						if FNI1<5000 then FENI1 = FNI1 ;
						else FENI1=min(10000,max(5000,labinc1));
						if FNI2<5000 then FENI2 = FNI2 ;
						else FENI2=min(10000,max(5000,labinc2));
					end ;
					else if fedyear<1928 and fedyear>1924 then do ;
						if FNI1<5000 then FENI1 = FNI1 ;
						else FENI1=min(20000,max(5000,labinc1));
						if FNI2<5000 then FENI2 = FNI2 ;
						else FENI2=min(20000,max(5000,labinc2));
					end ;
					else if fedyear<1932 and fedyear>1927 then do ;
						if FNI1<5000 then FENI1 = FNI1 ;
						else FENI1=min(30000,max(5000,labinc1));
						if FNI2<5000 then FENI2 = FNI2 ;
						else FENI2=min(30000,max(5000,labinc2));
					end ;					
				end ;
				/* married, community-property state */					
				else if Fseparate = 2 then do ;
					if fedyear=1924 then do ;
						if FNI1<5000 then FENI1 = FNI1 ;
						else FENI1=min(10000,max(5000,labinc/2));
 						if FNI2<5000 then FENI2 = FNI2 ;
						else FENI2=min(10000,max(5000,labinc/2));
					end ;
					else if fedyear<1928 and fedyear>1924 then do ;
						if FNI1<5000 then FENI1 = FNI1 ;
						else FENI1=min(20000,max(5000,labinc/2));
						if FNI2<5000 then FENI2 = FNI2 ;
						else FENI2=min(20000,max(5000,labinc/2));
					end ;
					else if fedyear<1932 and fedyear>1927 then do ;
						if FNI1<5000 then FENI1 = FNI1 ;
						else FENI1=min(30000,max(5000,labinc/2));
						if FNI2<5000 then FENI2 = FNI2 ;
						else FENI2=min(30000,max(5000,labinc/2));
					end ;					
				end ;

				/* Re-calculate federal earned income credit and subtract from 
					alternative capital gains computation tax liability, 1924-31 */
				/* 1924 */
				if fedyear=1924 then do ;

					/* single or joint */
					FoldEICti = max(0, min(FENI-Fxexempt,FNI-Fxexempt)) ;
	   	     	    %bracketreader(FoldEICti, FoldEICbase, Fxrate, Fxbracket, Fxbracknum) ;
		            FtaxALTCG = max(0, FtaxALTCG - .25*FoldEICbase) ;
		            
					/* married filing separately */
		            if Fseparate>0 then do;
						FoldEICti1 = max(0, min(FENI1-Fxexempt1excg,FNI1-Fxexempt1excg)) ;
						FoldEICti2 = max(0, min(FENI2-Fxexempt2excg,FNI2-Fxexempt2excg)) ;

	       		        %bracketreader(FoldEICti1, FoldEICbase1, Fxrate, Fxbracket, Fxbracknum) ;
		       	        FtaxALTCG1 = max(0, FtaxALTCG1 - .25*FoldEICbase1) ;
		       	        %bracketreader(FoldEICti2, FoldEICbase2, Fxrate, Fxbracket, Fxbracknum) ;
		       	        FtaxALTCG2 = max(0, FtaxALTCG2 - .25*FoldEICbase2) ;
					end ;

				end ;

				else if fedyear<1932 and fedyear>1924 then do ;	

					/* single or joint */
		            FoldEICti = max(0, FENI) ;
					FoldEICtix = max(0, min(FENI-Fxexempt,FNI-Fxexempt)) ;
	   	     	    %bracketreader(FoldEICti, FoldEICbase, Frate, Fbracket, Fbracknum) ;
	   	     	    %bracketreader(FoldEICtix, FoldEICbasex, Fxrate, Fxbracket, Fxbracknum) ;
		            FtaxALTCG = max(0, FtaxALTCG - .25*(FoldEICbase+FoldEICbasex)) ;
		            
					/* married filing separately*/
		            if Fseparate>0 then do;
						FoldEICti1 = max(0, FENI1) ;
						FoldEICti2 = max(0, FENI2) ;
						FoldEICti1x = max(0, min(FENI1-Fxexempt1excg,FNI1-Fxexempt1excg)) ;
						FoldEICti2x = max(0, min(FENI2-Fxexempt2excg,FNI2-Fxexempt2excg)) ;
			
	       		        %bracketreader(FoldEICti1, FoldEICbase1, Frate, Fbracket, Fbracknum) ;
   	    		        %bracketreader(FoldEICti1x, FoldEICbase1x, Fxrate, Fxbracket, Fxbracknum) ;
		       	        FtaxALTCG1 = max(0, FtaxALTCG1 - .25*(FoldEICbase1+FoldEICbase1x)) ;

	       		        %bracketreader(FoldEICti2, FoldEICbase2, Frate, Fbracket, Fbracknum) ;
   	    		        %bracketreader(FoldEICti2x, FoldEICbase2x, Fxrate, Fxbracket, Fxbracknum) ;
		       	        FtaxALTCG2 = max(0, FtaxALTCG2 - .25*(FoldEICbase2+FoldEICbase2x)) ;
					end ;
				end ;
			end ;
		end ;
		else if year<1948 then do ;
			FtaxALTCG=FtaxNORM ;
			if Fseparate>0 then do ;
				FtaxALTCG1=FtaxNORM1 ;
				FtaxALTCG2=FtaxNORM2 ;
			end ;
		end;

		/********************************************************************
		* 1943 Victory Tax and Tax Forgiveness								*
		*********************************************************************/
		if fedyear=1943 then do ;
			/* Calculate credit for 1942 tax assuming same income and
				deductions as 1943 */
			if iteration=1 and deductcycle=0 then do ;
				FtaxNORM_BV0 = FtaxNORM ;
				FtaxALTCG_BV0 = FtaxALTCG ;
				if Fseparate>0 then do ;
					FtaxNORM1_BV0 = FtaxNORM1 ;
					FtaxNORM2_BV0 = FtaxNORM2 ;
					FtaxALTCG1_BV0 = FtaxALTCG1 ;
					FtaxALTCG2_BV0 = FtaxALTCG2 ;
				end ;
			end ;
			else if iteration=1 and deductcycle=1 then do ;
				FtaxNORM_BV1 = FtaxNORM ;
				FtaxALTCG_BV1 = FtaxALTCG ;
				if Fseparate>0 then do ;
					FtaxNORM1_BV1 = FtaxNORM1 ;
					FtaxNORM2_BV1 = FtaxNORM2 ;
					FtaxALTCG1_BV1 = FtaxALTCG1 ;
					FtaxALTCG2_BV1 = FtaxALTCG2 ;
				end ;
			end ;
			else if iteration=1 and deductcycle=2 then do ;
				FtaxNORM_BV2 = FtaxNORM ;
				FtaxALTCG_BV2 = FtaxALTCG ;
				if Fseparate>0 then do ;
					FtaxNORM1_BV2 = FtaxNORM1 ;
					FtaxNORM2_BV2 = FtaxNORM2 ;
					FtaxALTCG1_BV2 = FtaxALTCG1 ;
					FtaxALTCG2_BV2 = FtaxALTCG2 ;
				end ;
			end ;
			else if iteration=1 and deductcycle=3 then do ;
				FtaxNORM_BV3 = FtaxNORM ;
				FtaxALTCG_BV3 = FtaxALTCG ;
				if Fseparate>0 then do ;
					FtaxNORM1_BV3 = FtaxNORM1 ;
					FtaxNORM2_BV3 = FtaxNORM2 ;
					FtaxALTCG1_BV3 = FtaxALTCG1 ;
					FtaxALTCG2_BV3 = FtaxALTCG2 ;
				end ;
			end ;
			else if iteration=1 and deductcycle=4 then do ;
				FtaxNORM_BV4 = FtaxNORM ;
				FtaxALTCG_BV4 = FtaxALTCG ;
				if Fseparate>0 then do ;
					FtaxNORM1_BV4 = FtaxNORM1 ;
					FtaxNORM2_BV4 = FtaxNORM2 ;
					FtaxALTCG1_BV4 = FtaxALTCG1 ;
					FtaxALTCG2_BV4 = FtaxALTCG2 ;
				end ;
			end ;
			else if iteration=1 and deductcycle=5 then do ;
				FtaxNORM_BV5 = FtaxNORM ;
				FtaxALTCG_BV5 = FtaxALTCG ;
				if Fseparate>0 then do ;
					FtaxNORM1_BV5 = FtaxNORM1 ;
					FtaxNORM2_BV5 = FtaxNORM2 ;
					FtaxALTCG1_BV5 = FtaxALTCG1 ;
					FtaxALTCG2_BV5 = FtaxALTCG2 ;
				end ;
			end ;
			else if iteration=1 and deductcycle=6 then do ;
				FtaxNORM_BV6 = FtaxNORM ;
				FtaxALTCG_BV6 = FtaxALTCG ;
				if Fseparate>0 then do ;
					FtaxNORM1_BV6 = FtaxNORM1 ;
					FtaxNORM2_BV6 = FtaxNORM2 ;
					FtaxALTCG1_BV6 = FtaxALTCG1 ;
					FtaxALTCG2_BV6 = FtaxALTCG2 ;
				end ;
			end ;

			/* single, head of household, or joint */
			if filertype ne "m" then 
				VicTaxTI = max(0, Fagi - (1-(Fcgexpct/100))*max(ltcg,0)-624) ;
			else VicTaxTI = max(0, Fagi - (1-(Fcgexpct/100))*max(ltcg,0)-1048) ;
			VicTax_bc = .05*VicTaxTI ;
			if filertype="s" then VicTaxCred = min((.25+.02*deps)*VicTax_bc, 500+100*deps) ;
			else if filertype="h" then VicTaxCred = 
				min((.4+.02*max(deps-1,0))*VicTax_bc, 1000+100*max(deps-1,0)) ;
			else if filertype="m" then VicTaxCred =
				min((.4+.02*max(deps,0))*VicTax_bc, 1000+100*max(deps,0)) ;
			VicTaxNORM = min(.9*max(0,Fti+Fexempt)-FtaxNORM, max(0, VicTax_bc - VicTaxCred)) ;
			VicTaxALTCG = min(.9*max(0,Fti+Fexempt)-FtaxALTCG, max(0, VicTax_bc - VicTaxCred)) ;
			/* married filing separately */
			if Fseparate>0 then do ;
				if Fseparate=1 then do ;
					VicTaxTI1 = max(0, Fagi1 - (1-(Fcgexpct/100))*ltcg1 - 624) ;
					VicTaxTI2 = max(0, Fagi2 - (1-(Fcgexpct/100))*ltcg2 - 624) ;
				end;
				else if Fseparate=2 then do ;
					VicTaxTI1 = max(0, Fagi1 - (1-(Fcgexpct/100))*(ltcg/2) - 624) ;
					VicTaxTI2 = max(0, Fagi2 - (1-(Fcgexpct/100))*(ltcg/2) - 624) ;
				end ;
				VicTax_bc1 = .05*VicTaxTI1 ;
				VicTax_bc2 = .05*VicTaxTI2 ;
				if Fagi1>=Fagi2 then do ;
					VicTaxCred1 = min((.4+.02*deps)*VicTax_bc, 500+100*deps) ;
					VicTaxCred2 = min(.4*VicTax_bc, 500) ;
				end ;
				else do ;
					VicTaxCred1 = min(.4*VicTax_bc, 500) ;
					VicTaxCred2 = min((.4+.02*deps)*VicTax_bc, 500+100*deps) ;
				end ;
				VicTaxNORM1 = min(.9*max(0,Fti1+Fexempt1)-FtaxNORM1,max(0, VicTax_bc1 - VicTaxCred1)) ;
				VicTaxNORM2 = min(.9*max(0,Fti2+Fexempt2)-FtaxNORM2,max(0, VicTax_bc2 - VicTaxCred2)) ;
				VicTaxALTCG1 = min(.9*max(0,Fti1+Fexempt1)-FtaxALTCG1,max(0, VicTax_bc1 - VicTaxCred1)) ;
				VicTaxALTCG2 = min(.9*max(0,Fti2+Fexempt2)-FtaxALTCG2,max(0, VicTax_bc2 - VicTaxCred2)) ;
			end ;
			/* tax liability after victory tax and tax forgiveness */
			if deductcycle=0 then do ;
				FtaxNORM = max(0, FtaxNORM + VicTaxNORM - .75*FtaxNORM_BV0) ;
				FtaxALTCG = max(0, FtaxALTCG + VicTaxALTCG - .75*FtaxALTCG_BV0) ;
				if Fseparate>0 then do ;
					FtaxNORM1 = max(0, FtaxNORM1 + VicTaxNORM1 - .75*FtaxNORM1_BV0) ;
					FtaxNORM2 = max(0, FtaxNORM2 + VicTaxNORM2 - .75*FtaxNORM2_BV0) ;
					FtaxALTCG1 = max(0, FtaxALTCG1 + VicTaxALTCG1 - .75*FtaxALTCG1_BV0) ;
					FtaxALTCG2 = max(0, FtaxALTCG2 + VicTaxALTCG2 - .75*FtaxALTCG2_BV0) ;
				end ;
			end ;
			else if deductcycle=1 then do ;
				FtaxNORM = max(0, FtaxNORM + VicTaxNORM - .75*FtaxNORM_BV1) ;
				FtaxALTCG = max(0, FtaxALTCG + VicTaxALTCG - .75*FtaxALTCG_BV1) ;
				if Fseparate>0 then do ;
					FtaxNORM1 = max(0, FtaxNORM1 + VicTaxNORM1 - .75*FtaxNORM1_BV1) ;
					FtaxNORM2 = max(0, FtaxNORM2 + VicTaxNORM2 - .75*FtaxNORM2_BV1) ;
					FtaxALTCG1 = max(0, FtaxALTCG1 + VicTaxALTCG1 - .75*FtaxALTCG1_BV1) ;
					FtaxALTCG2 = max(0, FtaxALTCG2 + VicTaxALTCG2 - .75*FtaxALTCG2_BV1) ;
				end ;
			end ;
			else if deductcycle=2 then do ;
				FtaxNORM = max(0, FtaxNORM + VicTaxNORM - .75*FtaxNORM_BV2) ;
				FtaxALTCG = max(0, FtaxALTCG + VicTaxALTCG - .75*FtaxALTCG_BV2) ;
				if Fseparate>0 then do ;
					FtaxNORM1 = max(0, FtaxNORM1 + VicTaxNORM1 - .75*FtaxNORM1_BV2) ;
					FtaxNORM2 = max(0, FtaxNORM2 + VicTaxNORM2 - .75*FtaxNORM2_BV2) ;
					FtaxALTCG1 = max(0, FtaxALTCG1 + VicTaxALTCG1 - .75*FtaxALTCG1_BV2) ;
					FtaxALTCG2 = max(0, FtaxALTCG2 + VicTaxALTCG2 - .75*FtaxALTCG2_BV2) ;
				end ;
			end ;
			else if deductcycle=3 then do ;
				FtaxNORM = max(0, FtaxNORM + VicTaxNORM - .75*FtaxNORM_BV3) ;
				FtaxALTCG = max(0, FtaxALTCG + VicTaxALTCG - .75*FtaxALTCG_BV3) ;
				if Fseparate>0 then do ;
					FtaxNORM1 = max(0, FtaxNORM1 + VicTaxNORM1 - .75*FtaxNORM1_BV3) ;
					FtaxNORM2 = max(0, FtaxNORM2 + VicTaxNORM2 - .75*FtaxNORM2_BV3) ;
					FtaxALTCG1 = max(0, FtaxALTCG1 + VicTaxALTCG1 - .75*FtaxALTCG1_BV3) ;
					FtaxALTCG2 = max(0, FtaxALTCG2 + VicTaxALTCG2 - .75*FtaxALTCG2_BV3) ;
				end ;
			end ;
			else if deductcycle=4 then do ;
				FtaxNORM = max(0, FtaxNORM + VicTaxNORM - .75*FtaxNORM_BV4) ;
				FtaxALTCG = max(0, FtaxALTCG + VicTaxALTCG - .75*FtaxALTCG_BV4) ;
				if Fseparate>0 then do ;
					FtaxNORM1 = max(0, FtaxNORM1 + VicTaxNORM1 - .75*FtaxNORM1_BV4) ;
					FtaxNORM2 = max(0, FtaxNORM2 + VicTaxNORM2 - .75*FtaxNORM2_BV4) ;
					FtaxALTCG1 = max(0, FtaxALTCG1 + VicTaxALTCG1 - .75*FtaxALTCG1_BV4) ;
					FtaxALTCG2 = max(0, FtaxALTCG2 + VicTaxALTCG2 - .75*FtaxALTCG2_BV4) ;
				end ;
			end ;
			else if deductcycle=5 then do ;
				FtaxNORM = max(0, FtaxNORM + VicTaxNORM - .75*FtaxNORM_BV5) ;
				FtaxALTCG = max(0, FtaxALTCG + VicTaxALTCG - .75*FtaxALTCG_BV5) ;
				if Fseparate>0 then do ;
					FtaxNORM1 = max(0, FtaxNORM1 + VicTaxNORM1 - .75*FtaxNORM1_BV5) ;
					FtaxNORM2 = max(0, FtaxNORM2 + VicTaxNORM2 - .75*FtaxNORM2_BV5) ;
					FtaxALTCG1 = max(0, FtaxALTCG1 + VicTaxALTCG1 - .75*FtaxALTCG1_BV5) ;
					FtaxALTCG2 = max(0, FtaxALTCG2 + VicTaxALTCG2 - .75*FtaxALTCG2_BV5) ;
				end ;
			end ;
			else if deductcycle=6 then do ;
				FtaxNORM = max(0, FtaxNORM + VicTaxNORM - .75*FtaxNORM_BV6) ;
				FtaxALTCG = max(0, FtaxALTCG + VicTaxALTCG - .75*FtaxALTCG_BV6) ;
				if Fseparate>0 then do ;
					FtaxNORM1 = max(0, FtaxNORM1 + VicTaxNORM1 - .75*FtaxNORM1_BV6) ;
					FtaxNORM2 = max(0, FtaxNORM2 + VicTaxNORM2 - .75*FtaxNORM2_BV6) ;
					FtaxALTCG1 = max(0, FtaxALTCG1 + VicTaxALTCG1 - .75*FtaxALTCG1_BV6) ;
					FtaxALTCG2 = max(0, FtaxALTCG2 + VicTaxALTCG2 - .75*FtaxALTCG2_BV6) ;
				end ;
			end ;
		end ;

		/********************************************************************
		* Limitation on effective federal tax rate, 1944-47                 *
		*********************************************************************/
		if (fedyear=1944 or fedyear=1945) then do ;
			FtaxNORM = min(FtaxNORM, .9*max(Fti+Fexempt,0)) ;
			FtaxALTCG = min(FtaxALTCG, .9*max(Fti+Fexempt,0)) ;
			if Fseparate=1 then do ;
				FtaxNORM1 = min(FtaxNORM1, .9*max(Fti1+Fexempt1,0)) ;
				FtaxALTCG1 = min(FtaxALTCG1, .9*max(Fti1+Fexempt1,0)) ;
				FtaxNORM2 = min(FtaxNORM2, .9*max(Fti2+Fexempt2,0)) ;
				FtaxALTCG2 = min(FtaxALTCG2, .9*max(Fti2+Fexempt2,0)) ;
			end ;
		end ;
		else if (fedyear=1946 or fedyear=1947) then do ;
			FtaxNORM = min(FtaxNORM, .855*max(Fti+Fexempt,0)) ;
			FtaxALTCG = min(FtaxALTCG, .855*max(Fti+Fexempt,0)) ;
			if Fseparate=1 then do ;
				FtaxNORM1 = min(FtaxNORM1, .855*max(Fti1+Fexempt1,0)) ;
				FtaxALTCG1 = min(FtaxALTCG1, .855*max(Fti1+Fexempt1,0)) ;
				FtaxNORM2 = min(FtaxNORM2, .855*max(Fti2+Fexempt2,0)) ;
				FtaxALTCG2 = min(FtaxALTCG2, .855*max(Fti2+Fexempt2,0)) ;
			end ;
		end ;

        /*******************************************************************
        *  Federal tax liability before credits (Fdtxliab_bc), before 1948 *
        ********************************************************************/
		if Fedyear<1948 then do ;
			Fdtxliab_bc = min(FtaxNORM, FtaxALTCG) ;
			if Fseparate=1 then do ;
				Fdtxliab_bc1 = min(FtaxNORM1, FtaxALTCG1) ;
				Fdtxliab_bc2 = min(FtaxNORM2, FtaxALTCG2) ;
			end ;

			/****************************************************************************
			* Federal defense tax, 1940								                    *
			* minimum of 10% of tax liability, not to exceed 10% of net income less tax *
			*****************************************************************************/
			if fedyear=1940 then do ;
				Fdeftax = .1*min(max(Fdtxliab_bc,0),max(Fti+Fexempt-Fdtxliab_bc,0)) ;
				if Fseparate=1 then do ;
					Fdeftax1 = .1*min(max(Fdtxliab_bc1,0),max(Fti1+Fexempt1-Fdtxliab_bc1,0)) ;
					Fdeftax2 = .1*min(max(Fdtxliab_bc2,0),max(Fti2+Fexempt2-Fdtxliab_bc2,0)) ;
				end ;
				Fdtxliab_bc = Fdtxliab_bc + Fdeftax ;
				if Fseparate=1 then do ;
					Fdtxliab_bc1 = Fdtxliab_bc1 + Fdeftax1 ;
					Fdtxliab_bc2 = Fdtxliab_bc2 + Fdeftax2 ;
				end ;
			end ;

			if Fseparate=1 then do ;
				if(Fdtxliab_bc1+Fdtxliab_bc2) < Fdtxliab_bc then do ;
					Fdtxliab_bc = Fdtxliab_bc1 + Fdtxliab_bc2 ;
					Fsepfiler=1 ;
					FtaxNORM=FtaxNORM1+FtaxNORM2 ;
					FtaxALTCG=FtaxALTCG1+FtaxALTCG2 ;
					FmtrNORM=FmtrNORM1 ;
					Fti=Fti1+Fti2 ;
					Fexempt=Fexempt1+Fexempt2 ;
				end ;
				else Fsepfiler=0 ;
			end ;
			else Fsepfiler=0 ;
		end ;
	end ;

%mend fedtax5 ;
%macro FedYearSelector ; 	
	%if &yearstart < 1948 %then %fedtax5 ; 
%mend FedYearSelector ; 
%FedYearSelector ;	


/***************************************************************
* Final federal tax liability calculation    				   *
****************************************************************/
%macro fedtax6 ; 

        /***********************************************************
        * Federal child credit (Fkidcred)                          *
        ************************************************************/
        if Fkidc>0 and kids3>0 then do;
                if Fagi<Fkidcthresh then FkidcredGROSS=Fkidc*kids3 ;
                else if Fagi>=Fkidcthresh then
                        FkidcredGROSS=max(0, Fkidc*kids3 - (Fkidcrate/100)*(max(Fagi,0)-Fkidcthresh));
        end;
        else FkidcredGROSS=0;
		Fkidcred = min(FkidcredGROSS,max(0,Fdtxliab_bc+(fedyear>1999)*Famt-fdcred-Fkcarecred-Feldcred)) ;
        /* refundable portion */
        if FkidcredGROSS>(Fdtxliab_bc+(fedyear>1999)*Famt-fdcred-Fkcarecred-Feldcred) then do;
                Fkidcredref1=min((Fkidcrefrate/100)*max(0,earnedinc-Fkidcrefinc),
                	max(0,FkidcredGROSS-max(0,Fdtxliab_bc+(fedyear>1999)*Famt-fdcred-Fkcarecred-Feldcred)));
				if kids3>2 then Fkidcredref2 = 
						min(max(((Fsstxliab1+Fsstxliab2)*.5 + FsstxliabSE1 + FsstxliabSE2)-Feic,0), 
						max(0,FkidcredGROSS-max(0,Fdtxliab_bc+(fedyear>1999)*Famt-fdcred-Fkcarecred-Feldcred)));
				else Fkidcredref2=0 ;
				Fkidcredref=max(Fkidcredref1,Fkidcredref2,0) ;
        end;
        else Fkidcredref=0;

		/*************************************************************
		* Fdivcred -- Federal credit for dividends (applied 1954-64) *
		**************************************************************/
		if (fedyear>=1954 and fedyear<1955) then do ;
			if FtaxALTCG<FtaxNORM then Fdivcred = min(.04*max(0,(5/12)*div - Fdivexamt), .02*max(FtiEXCG,0)) ;
			else Fdivcred = min(.04*max(0,(5/12)*div - Fdivexamt), .02*max(Fti,0)) ;
		end ;
		else if (fedyear>=1955 and fedyear<1958) then do ;
			if FtaxALTCG<FtaxNORM then Fdivcred = min(.04*max(0,div - Fdivexamt), .04*max(FtiEXCG,0)) ;
			else Fdivcred = min(.04*max(0,div - Fdivexamt), .04*max(Fti,0)) ;
		end ;
		else if (fedyear>=1958 and fedyear<1964) then Fdivcred = min(.04*max(0,div - Fdivexamt), .04*max(Fti,0)) ;
		else if (fedyear>=1964 and fedyear<1965) then Fdivcred = min(.02*max(0,div - Fdivexamt), .02*max(Fti,0)) ;
		else Fdivcred=0 ;

        /**************************************************************************
        * Federal income tax liability, after *everything* is taken into account  *
        * (taxf)                                                                  *
        ***************************************************************************/
        taxf = max(0, Fdtxliab_bc + (fedyear>=2000)*Famt - fdcred - Fkidcred - Fkcarecred
                -Fgencred - Fdivcred - Feldcred) + FtaxMIN + (fedyear<2000)*Famt - Feic - Fkidcredref ;

           /**************************************************************
		   * If subject to AMT or minimum tax, or if federal itemization *
		   * decision constrains state itemization decision,			 *
           * compare tax liability with and without itemizing.           *
           * If switching itemization status reduces liability, 		 *
		   * then re-define variables to be consistent with the new      *
		   * new itemization status						                 *
           ***************************************************************/
			if (Famt>0 or FtaxMIN>0 or itemiz>1 or mintaxtype=5) then do;

				/*************************************************** 
				Recalculate nonrefundable portion of child credit
				for switched itemization status
				****************************************************/
				FkidcredSI = min(FkidcredGROSS,max(0,Fdtxliab_bcSI+(fedyear>=2000)*FamtSI-fdcred-Fkcarecred-Feldcred)) ;

				/****************************************************
				Recalculate refundable portion of child credit
				for switched itemization status.
				*****************************************************/
        		if FkidcredGROSS>(Fdtxliab_bcSI+(fedyear>=2000)*FamtSI-fdcred-Fkcarecred-Feldcred) then do;
                	Fkidcredref1SI=min((Fkidcrefrate/100)*max(0,earnedinc-Fkidcrefinc),
                		max(0,FkidcredGROSS-max(0,Fdtxliab_bcSI+(fedyear>=2000)*FamtSI-fdcred-Fkcarecred-Feldcred)));
					if kids3>2 then Fkidcredref2SI = 
						min(max(((Fsstxliab1+Fsstxliab2)*.5 + FsstxliabSE1 + FsstxliabSE2)-Feic,0), 
						max(0,FkidcredGROSS-max(0,Fdtxliab_bcSI+(fedyear>=2000)*FamtSI-fdcred-Fkcarecred-Feldcred)));
					else Fkidcredref2SI=0 ;
					FkidcredrefSI=max(Fkidcredref1SI,Fkidcredref2SI,0) ;
        		end;
        		else FkidcredrefSI=0;

				/**************************************************************************
				* Fdivcred -- Federal credit for dividends (applied 1954-64) 			  *
				* Re-calculate for switched itemization status							  *
				***************************************************************************/
				if (fedyear>=1954 and fedyear<1955) then do ;
					if FtaxALTCGSI<FtaxNORMSI then FdivcredSI = min(.04*max(0,(5/12)*div - Fdivexamt), .02*max(FtiEXCGSI,0)) ;
					else FdivcredSI = min(.04*max(0,(5/12)*div - Fdivexamt), .02*max(FtiSI,0)) ;
				end ;
				else if (fedyear>=1955 and fedyear<1958) then do ;
					if FtaxALTCGSI<FtaxNORMSI then FdivcredSI = min(.04*max(0,div - Fdivexamt), .04*max(FtiEXCGSI,0)) ;
					else FdivcredSI = min(.04*max(0,div - Fdivexamt), .04*max(FtiSI,0)) ;
				end ;
				else if (fedyear>=1958 and fedyear<1964) then FdivcredSI = min(.04*max(0,div - Fdivexamt), .04*max(FtiSI,0)) ;
				else if (fedyear>=1964 and fedyear<1965) then FdivcredSI = min(.02*max(0,div - Fdivexamt), .02*max(FtiSI,0)) ;
				else FdivcredSI=0 ;


				/* recalculate tax liability */
				taxfSI = max(0, Fdtxliab_bcSI + (fedyear>=2000)*FamtSI - fdcred - FkidcredSI - Fkcarecred
                	-Fgencred - FdivcredSI - Feldcred) + FtaxMINSI + (fedyear<2000)*FamtSI 
					- Feic - FkidcredrefSI ;

				/* If this is the first cycle of iterations (before adding MTR increment), choose the itemization status that 
				minimizes combined federal and state tax liability.  If this is not the first cycle of iterations (i.e., 
				MTR increment has been added), then itemization status is constrained to be the same as in the corresponding
				iteration of the first cycle. */
				if iteration=1 then do ;
					if (taxfSI + (Fitemizer=0)*taxsFYI + (Fitemizer=1)*taxsFNI)
					< (taxf + (Fitemizer=1)*taxsFYI + (Fitemizer=0)*taxsFNI)
					then do ;
						/* Preserve original values of key variables that have not already been preserved */
						taxf_X = taxf ;
						Fkidcred_X = Fkidcred ;
						Fkidcredref_X = Fkidcredref ;
						Fdivcred_X = Fdivcred ;

						/* Set final values of variables equal to switched itemization status values */
                    	Fitemizer = FitemizerSI ;
						taxf = taxfSI ;
                		Famt = FamtSI ;
						Fdtxliab_bc = Fdtxliab_bcSI;
                    	Ftamt = FtamtSI ;
                    	Famti = FamtiSI ;
                    	Famtiae = FamtiaeSI ;
                    	Fti = FtiSI ;
                    	FtaxNORM = FtaxNORMSI ;
                    	FmtrNORM = FmtrNORMSI;
                    	FmtrNORM2 = FmtrNORMSI;
                    	Famtpref= FamtprefSI ;
						FtaxALTCG = FtaxALTCGSI ;
						FtaxMAXEI = FtaxMAXEISI ;
						FtaxINCAVG = FtaxINCAVGSI ; 
						FmtrMEI = FmtrMEISI ;
						FtaxMIN = FtaxMINSI ;
						Ftaxpref = FtaxprefSI ;	
						Famtexempt = FamtexemptSI ; 
						FamtiaeEXCG = FamtiaeEXCGSI ; 
						FtamtEXCG = FtamtEXCGSI ;
						CGa = CGaSI ; 
						CGaX = CGaXSI ; 
						CGb = CGbSI ; 
						CGbX = CGbXSI ;
						FtamtALTCG = FtamtALTCGSI ; 
						FtaxCGaX = FtaxCGaXSI ; 
						FtaxCGbX = FtaxCGbXSI ;
						Fkidcred = FkidcredSI ;
						Fkidcredref = FkidcredrefSI ;
						Fdivcred = FdivcredSI ;

						/* Set switched itemization status variables equal to original values before switching itemization */
                    	FitemizerSI = Fitemizer_X ;
						taxfSI = taxf_X ;
                		FamtSI = Famt_X ;
						Fdtxliab_bcSI = Fdtxliab_bc_X ;
                    	FtamtSI = Ftamt_X ;
                    	FamtiSI = Famti_X ;
                    	FamtiaeSI = Famtiae_X ;
                    	FtiSI = Fti_X ;
						FtiEXCGSI = FtiEXCG_X ;
                    	FtaxNORMSI = FtaxNORM_X ;
                    	FmtrNORMSI = FmtrNORM_X ;
                    	FmtrNORM2SI = FmtrNORM_X ;
                    	FamtprefSI = Famtpref_X ;
						FtaxALTCGSI = FtaxALTCG_X ;
						FtaxMAXEISI = FtaxMAXEI_X ;
						FtaxINCAVGSI = FtaxINCAVG_X ; 
						FmtrMEISI = FmtrMEI_X ;
						FtaxMINSI = FtaxMIN_X ;
						FtaxprefSI = Ftaxpref_X ;	
						FamtexemptSI = Famtexempt_X ; 
						FamtiaeEXCGSI = FamtiaeEXCG_X ; 
						FtamtEXCGSI = FtamtEXCG_X ;
						CGaSI = CGa_X ; 
						CGaXSI = CGaX_X ; 
						CGbSI = CGb_X ; 
						CGbXSI = CGbX_X ;
						FtamtALTCGSI = FtamtALTCG_X ; 
						FtaxCGaXSI = FtaxCGaX_X ; 
						FtaxCGbXSI = FtaxCGbX_X ;
						FkidcredSI = Fkidcred_X ;
						FkidcredrefSI = Fkidcredref_X ;
						FdivcredSI = Fdivcred_X ;
					end ;
                end;
			end ;

		/**************************************************************************
		* Limitations on maximum effective federal tax rate, 1948-63              *
		***************************************************************************/
		if (fedyear=1948 or fedyear=1949) then taxf = min(taxf, .77*max(Fti+Fexempt,0)) ;
		else if (fedyear=1950) then taxf = min(taxf, .87*max(Fti+Fexempt,0)) ;
		else if (fedyear=1951) then taxf = min(taxf, .872*max(Fti+Fexempt,0)) ;
		else if (fedyear=1952 or fedyear=1953) then taxf = min(taxf, .88*max(Fti+Fexempt,0)) ;
		else if (fedyear>1953 and fedyear<1964) then taxf = min(taxf, .87*max(Fti,0)) ;

end ;
%mend fedtax6 ; 	
%fedtax6 ;			
%mend fedtax ; 		
/*************************************************************************************
*                               End of FEDTAX                                        *
**************************************************************************************/




/**************************************************************************************
***************************************************************************************
***************************************************************************************
***************************************************************************************
***************************************************************************************
*****																			  *****
*****                       E.   STATETAX MACRO                                   *****
*****   			macro that performs state tax calculations                    *****
*****																			  *****
***************************************************************************************
***************************************************************************************
***************************************************************************************
***************************************************************************************
***************************************************************************************/

%macro statetax; 

/* The statetax1 macro performs the complete state tax calculation.  At the
end of the statetax macro, statetax1 is run once with no constraints on state itemization
status, and then run again with any constraints on state itemization status given
federal itemization status that are imposed by state law, for those records
where constrained and unconstrained itemization status differ.  The difference
in state tax liability between unconstrained and constrained then feeds back
into the federal itemization decision in the fedtax macro. */

%macro statetax1 ; 

/*** Start state tax calculation for states where tax is a function of income ***/
if taxtype="pctinc" then do;

        /********************************************************************************
        State filing status for married couples:										
		If married couples *may* find it advantageous to file separate state income tax
		returns, the variable "separate" is set to 1.  In those cases, the program
		computes tax liability both ways (separate filing and joint filing), and chooses
		the status with the lower state tax liability.
        *********************************************************************************/
        if filertype="m" and (multbrk=0 and (sepdis=0 or sepdis=2) and comprop=0 and bracknum>1)
                then separate=1;
        else separate=0;

		/********************************************************************************* 
		* Set federal tax parameters used in state tax calculations to zero              *
		* for years before 1913 														 *
		**********************************************************************************/
		if Fmarded=. then Fmarded=0 ;
		if Fmovexded=. then Fmovexded=0 ;
		if Fbusexded=. then Fbusexded=0 ;
		if Fminexlim=. then Fminexlim=0 ;
		if Fexlimrate=. then Fexlimrate=0 ;
		if Fmedded=. then Fmedded=0 ;
		if Fcasdedlim=. then Fcasdedlim=0 ;
		if Fidphrate=. then Fidphrate=0 ;
		if Famtexrate=. then Famtexrate=0 ;
		if Famtex=. then Famtex=0 ;
		if Famtexth=. then Famtexth=0 ;
		if Famttype=. then Famttype=0 ;
		if Fxtaxtype='' then Fxtaxtype="none" ;

        /**********************
        * Calculate state AGI *
        ***********************/

        /* For states that start with gross income */
        if base="gi" then do;

                /* State excluded capital gains (exltcg) */
                exltcg=min((cgexpct/100)*ltcg + cgexamt, ltcg);
				/* Special treatment of capital gains applying briefly in Maryland */
                if sptx="cgexmd" then do;
                        if (filertype="s" or filertype="h") then do ;
                                if Fagi<50000 then exltcg=min(7500, .3*ltcg);
                                else exltcg=max(min(.3*ltcg,7500)-.5*(Fagi-50000),0);
                        end;
                        else if filertype="m" then do;
                                if Fagi<100000 then exltcg=min(15000, .3*ltcg);
                                else exltcg=max(min(.3*ltcg,15000)-.5*(Fagi-100000),0);
                        end;
                end;
				/* Special capital gains exclusion in New Mexico */
				if sptx="cgexmax" then exltcg=max(max(min(ltcg,sptxex),(sptxrate/100)*ltcg),0) ;

                /* State AGI except social security */
                agi= wagsal + businc + farminc
				+ (ltcg-exltcg) + othcg + pension + rentinc + partscorp + othinc
                +max(0, div-(divexpct/100)*div - divexamt)
                +max(0, int-(intexpct/100)*int - intexamt)
                -min(div+int, diexamt)
                +(conform>1)*(Fuiagi-othadj)
                -(filertype="m")*(mardedtype=1)*((Fmarded=1)*0.05+(Fmarded=2)*0.1)*max(min(labinc1,labinc2,30000),0)
                -(1-Fmovexded)*movex
                -(1-Fbusexded)*busex 
				- (stateyear>1989)*(conform>1)*(1/2)*(FsstxliabSE1+FsstxliabSE2);

                /* Social security benefits included in state AGI (ssagi) */
                if ssben>0 then do;
                        if ssbentx=1 then ssagi=Fssagi;
                        else if ssbentx=2 then ssagi=ssben;
                        else if ssbentx=3 then do ;
                                if (filertype="s" or filertype="h") and 
									(Fagi+(.5*ssben))>=25000
                                        then ssagi=min(0.5*ssben, .5*(0.5*ssben+Fagi-25000));
                                else if filertype="m" and
									(Fagi+(.5*ssben))>=32000
                                        then ssagi=min(0.5*ssben, .5*(0.5*ssben+Fagi-32000));
								else ssagi=0 ;
                        end;
						else ssagi=0 ;
                end;
                else ssagi=0;

				agi = agi+ssagi ;
        		
			/* State AGI for separate filers */
			if separate=1 then do ;
                /* State excluded capital gains (exltcg) */
                exltcg1=min((cgexpct/100)*ltcg1 + cgexamt/2, ltcg1);
                exltcg2=min((cgexpct/100)*ltcg2 + cgexamt/2, ltcg2);

				agi1 = wagsal1 + businc1 + farminc1 + (ltcg1 - exltcg1) 
				+ othcg1 + pension1 + rentinc1 + partscorp1 + othinc1
            	+max(0, div1-(divexpct/100)*div1 - divexamt)
            	+max(0, int1-(intexpct/100)*int1 - intexamt)
            	-min(div1+int1, diexamt)
            	+(conform>1)*(Fuiagi*(ui1/max(ui,1))-othadj1)
				+ssagi*(ssben1/max(1,ssben))
            	-(1-Fmovexded)*movex1
            	-(1-Fbusexded)*busex1 
				-(stateyear>1989)*(conform>1)*(1/2)*FsstxliabSE1;

				agi2 = wagsal2 + businc2 + farminc2 + (ltcg2-exltcg2) 
				+ othcg2 + pension2 + rentinc2 + partscorp2 + othinc2
            	+max(0, div2-(divexpct/100)*div2 - divexamt)
            	+max(0, int2-(intexpct/100)*int2 - intexamt)
            	-min(div2+int2, diexamt)
            	+(conform>1)*(Fuiagi*(ui2/max(ui,1))-othadj2)
				+ssagi*(ssben2/max(1,ssben))
            	-(1-Fmovexded)*movex2
            	-(1-Fbusexded)*busex2 
				-(stateyear>1989)*(conform>1)*(1/2)*FsstxliabSE2;
			end ;
		end;

        /* For states that only tax components of capital income */
        else do ;
                if base="cg" then do;
                	agi=max(0, (1-(cgexpct/100))*ltcg - cgexamt + othcg) ;
                end;
                else if base="div" then agi=max(0,(1-(divexpct/100))*div - divexamt);
                else if base="di" then do ;
					agi=max(0,(1-(divexpct/100))*(div+((statename="nh")+(statename="tn"))*partscorp) - divexamt)
                    + max(0,(1-(intexpct/100))*int - intexamt);
					if separate=1 then do ;
						agi1=max(0,(1-(divexpct/100))*(div1+((statename="nh")+(statename="tn"))*partscorp1)- divexamt)
                       	+ max(0,(1-(intexpct/100))*int1 - intexamt);
						agi2=max(0,(1-(divexpct/100))*(div2+((statename="nh")+(statename="tn"))*partscorp2) - divexamt)
                       	+ max(0,(1-(intexpct/100))*int2 - intexamt);
					end ;
				end ;
                else if base="dcg" then do ;
                        agi=max(0,(1-(cgexpct/100))*ltcg-cgexamt + othcg)
                                +max(0,(1-(divexpct/100))*div-divexamt) ;
                end;
                else if base="dcgi" then do;
                        agi=max(0,(1-(cgexpct/100))*ltcg-cgexamt + othcg)
                        	+max(0,(1-(divexpct/100))*div-divexamt)
                        	+max(0,(1-(intexpct/100))*int - intexamt);
						if separate=1 then do ;
                        	agi1=max(0,(1-(cgexpct/100))*ltcg1-cgexamt + othcg1)
                                +max(0,(1-(divexpct/100))*div1-divexamt)
                                +max(0,(1-(intexpct/100))*int1 - intexamt);
                        	agi2=max(0,(1-(cgexpct/100))*ltcg2 - cgexamt + othcg2)
                                +max(0,(1-(divexpct/100))*div2 - divexamt)
                                +max(0,(1-(intexpct/100))*int2 - intexamt);							
						end ;
                end;
                ssagi=0;
				ssagi1=0;
				ssagi2=0;
        end;

        /* Percentage exemption */
        if base ne "fti" then do ;
			agi=agi*(1-(pctex/100));
			if separate=1 then do ;
				agi1=agi1*(1-(pctex/100));
				agi2=agi2*(1-(pctex/100));
			end ;
		end;

        /*************************************
        * State personal exemptions (exempt) *
        **************************************/
        exempt=expercap*(1 + (Filertype="m") + deps)
                + exreturn + (ex_dep * deps) + (ex_age * agenum) ;
			/* Exemptions that are prorated by ratio of state to federal AGI */
        	if exprorat=1 then exempt=exempt*min(1,(max(agi,0)/max(Fagi,1)));
			/* Special MA spousal exemption */
			if kidcaretype=4 and filertype="m" then exempt = 
				exempt + min(kc5, min(labinc1,labinc2)) + (min(labinc1,labinc2)<kc5)*kc6; 
			/* Extra NC personal exemption */
			if miscextype=14 and Fagi<lowph1 then exempt = exempt +
				miscexamt*(1 + (Filertype="m") + deps) ;
			/* Extra KS personal exemption */
			if miscextype=16 and filertype="h" then exempt = 
				exempt + expercap ;

        /**************************************************************************
        * State personal exemption phase-out tied to federal, 1991 and after.     *
        ***************************************************************************/
        if exlim=1 and agi>=Fminexlim then
                exempt=max(exempt-(agi-Fminexlim)*(Fexlimrate/100)*exempt,0);
 
       /**************************************************************************
        * States where exemptions are deducted against lowest brackets           *
		* (These have already been incorporated in bracket structure above)      *
        **************************************************************************/
		if exlim=2 then exempt=0 ;

		/*********************************************************************
		* State deductions for child care expenses 							 *
		**********************************************************************/
		if kidcaretype>0 and kidcaretype<11 and kids1>0 then do ;

			if kidcaretype=1 then do ;
				kcareded = Fkcareded ;
				kcareadj = 0 ;
			end ;
			else if kidcaretype=2 then do ;
				kcareded = 0 ;
				kcareadj = Fkcareded ;
			end ;
			else if kidcaretype=3 or (kidcaretype=4 and stateyear=1976) then do ;
				if filertype ne "m" then do ; 
					if kids1=1 then kcareded=min(childcare,2400,ei2sp) ;
					else if kids1=2 then kcareded=min(childcare,3600,ei2sp) ;
					else if kids1>2 then kcareded=min(childcare,4800,ei2sp) ;
				end ;
				else if Fagi<18000 then do ;
					if kids1=1 then kcareded=min(childcare,2400,ei2sp) ;
					else if kids1=2 then kcareded=min(childcare,3600,ei2sp) ;
					else if kids1>2 then kcareded=min(childcare,4800,ei2sp) ;
				end ;
				else do ;
					if kids1=1 then kcareded=
						max(0,min(childcare,2400,ei2sp)-.5*max(Fagi-18000,0)) ;
					else if kids1=2 then kcareded=
						max(0,min(childcare,3600,ei2sp)-.5*max(Fagi-18000,0)) ;
					else if kids1>2 then kcareded=
						max(0,min(childcare,4800,ei2sp)-.5*max(Fagi-18000,0)) ;
				end;
				kcareadj=0 ;					
			end ;
			else if kidcaretype=4 then do ;
				if stateyear = 1976 then do ;
					kcareadj=kcareded ;
					kcareded=0 ;
				end ;
				else if stateyear=1975 or (stateyear>1976 and stateyear<2001) then do ;
					kcareadj=max(Fkcareded,kc1*(kids1>0)) ;
					kcareded=0 ;
				end ;
				else if stateyear>=2001 then do ;
					if kids1=1 then kcareadj=max(min(ei2sp,kc3,childcare),kc1) ;
					else if kids1>1 then kcareadj=max(min(ei2sp,kc4,childcare),kc2) ;
					kcareded=0 ;					
				end ;
				else do ;
					kcareadj=0 ;
					kcareded=0 ;
				end ;
			end ;
			else if kidcaretype=5 then do ;
				kcareadj=0 ;
				if kids1=1 then kcareded=kc1 ;
				else if kids1=2 then kcareded=kc2 ;
				else if kids1>2 then kcareded=kc3 ;
				else kcareded=0 ;
				if kc5>0 and agi>=kc4 then do ;
					if kc4=kc5 then kcareded=0 ;
					else kcareded=max(0,kcareded*(1-min(1,max(0,agi-kc4)/(kc5-kc4)))) ;
				end ;
				else if kc5=0 and agi>=kc4 then do ;
					kcareded=max(0,kcareded - kcareded*min(1,max(0,agi-kc4)*(kc6/100))) ;
				end ;
			end ;
			else if kidcaretype=6 then do ;
				kcareadj=0 ;
				if agi1<(kc1 + deps*(ex_dep + expercap)) then kcareded=min(childcare,ei2sp) ;
				else kcareded=0 ;
			end ;
			else if kidcaretype=7 then do ;
				kcareadj=0 ;
				if kids1=1 then kcareded=min(childcare,kc1,ei2sp) ;
				else if kids1>1 then kcareded=min(childcare,kc2,ei2sp) ;
				else kcareded=0 ;
			end ;
		end ;
		else do ;
			kcareded=0 ;
			kcareadj=0 ;
		end ;

        /*********************************************************************
        *  State itemized deductions 			                             *
        *  itemded = value of allowable itemized deductions before phase-out *
        *  ssded = value of deductible social security payroll taxes         *
        *  itemcred = value of flat-rate credit for itemized deducitons      *
		*  Note that itemded is calculated later on if itemiz=4 or base=fti  *
        **********************************************************************/
		if itemiz ne 4 and base ne "fti" then do ;
	        itemded=
	          (charded>0)*min(charity,max(0,(chlim/100)*agi))
	        + intded*(intpaid+invint)
	        + sitded*(taxs_S + (Fsaleded=2)*max(salestax-taxs_S,0) ) 
	        + (propded=1)*proptax
	        + saleded*salestax
	        + (propded=1)*tax_nonincome_S
	        + (medded=1)*max(0,medexp-(Fmedded/100)*max(Fagi,0))
			+ kcareded
	        + (itemiz>0)*
			  (max(0,casualty-(Fcasdedlim/100)*max(Fagi,0)-100)
	        + Fmovexded*movex
	        + Fbusexded*max(0,busex+miscdedlim-.02*max(Fagi,0))
	        + (1-Fbusexded)*miscdedlim
	        + omiscded) ;
		end ;

		/* Is limit on deductible charity binding? */
		if charded>0 and (charity > (chlim/100)*agi) then do ;
			if chlim<50 and itemiz<2 and (statename ne "ca") then chlimbind=1 ;
			else chlimbind=2 ;
		end ;
		else chlimbind=0 ;		

		/*************************************************************
		*  Non-itemizer charitable deduction						 *
		**************************************************************/
		if charded = 2 then do ;
			if Fcharded=2 then SNIcharded=0.25*min(100,min(charity,max(0,(chlim/100)*agi))) ;
			else if Fcharded=3 then SNIcharded=0.25*min(300,min(charity,max(0,(chlim/100)*agi))) ;
			else if Fcharded=4 then SNIcharded=0.5*min(charity,max(0,(chlim/100)*agi)) ;
			else if Fcharded=5 then SNIcharded=min(charity,max(0,(chlim/100)*agi)) ;
			else SNIcharded=0 ;
		end ;
		else if charded = 3 and Fcharded>1 and Fcharded<6 then SNIcharded=0.25*min(300,min(charity,max(0,(chlim/100)*agi))) ;
		else if charded = 4 then SNIcharded=0.5*max(min(charity,max(0,(chlim/100)*agi))-500,0) ;	
		else SNIcharded=0 ;

		/**************************************************************
		* Special deduction for property tax and/or rent (IN, MA, NJ) *
		***************************************************************/
		if cbtype=10 then itemded = itemded + min((xcbrenteq/100)*rentpay,xcbmaxcr1)
				+ min(proptax,xcbmaxcr2) ;
		else if cbtype=15 then 
			itemded = itemded + min((xcbpct1/100)*rentpay,xcbmaxcr1) ;
		else if cbtype=17 and (income>xcbthresh5 or agenum>0) then 
			itemded = itemded + 
			min((cbincval1/100)*(proptax+(xcbrenteq/100)*rentpay),cbmaxhome) ;

        /*************************************************** 
		* Deduction for social security payroll tax        *
		****************************************************/
        if sstxded=1 then ssded=((Fsstxliab1+Fsstxliab2)*.5)+FsstxliabSE1+FsstxliabSE2 ;
        else if sstxded>1 then ssded=min(sstxded,(Fsstxliab1*.5)+FsstxliabSE1)+min(sstxded,(Fsstxliab2*.5)+FsstxliabSE2);
        else ssded=0;
        itemded=itemded+ssded;
			/* Separate filers */
        	if sstxded=1 then do ;
				ssded1=(Fsstxliab1*.5)+FsstxliabSE1 ;
				ssded2=(Fsstxliab2*.5)+FsstxliabSE2 ;
			end ;
        	else if sstxded>1 then do ;
				ssded1=min(sstxded,(Fsstxliab1*.5)+FsstxliabSE1);
				ssded2=min(sstxded,(Fsstxliab2*.5)+FsstxliabSE2);
			end ;
        	else do ;
				ssded1=0; ssded2=0 ;
			end ;			

        /****************************************************************************
        * State standard deduction  (stded)                                         *
        * minsd = minimum standard deduction after adjusting for age and dependents *
        * maxsd = maximum standard deduction after adjusting for age and dependents *
        *****************************************************************************/
        minsd = minstded + (minstded_d * deps) + (minstded_a * agenum) ;
        maxsd = maxstded + (maxstded_d * deps) + (maxstded_a * agenum) ;
        if pctstded=0 then stded = maxsd;
        else stded=min(maxsd,max((pctstded/100)*agi,minsd));
			/* special minimum standard deduction, Wisconsin, 1976(?)-1985 */
			if lowtype=19 then do ;
				minsd_adult = low  + agenum*loweldamt ;
				minsd_kid = deps*lowdepamt ;
				minsd_adult = max(1300, minsd_adult - max(0,minsd_adult-1300)*
						max(0, max(0,agi-(lowph1+lowphdep*agenum))/
						((lowph2+(200*(filertype="m"))+(300*agenum))-(lowph1+lowphdep)))) ;
				minsd_kid = max(0,minsd_kid - max(0,max(0,agi-5000)/(12000-5000))) ;
				stded = max(minsd_adult+minsd_kid, stded+minsd_kid) ;
			end ;


        /*** Phase-out of standard deduction (applied, e.g., in WI) ***/
        if dpthresh1>0 and dpthresh2=0 and agi>=dpthresh1 then
                stded=max(0,stded-(dprate1/100)*(agi-dpthresh1));
        if dpthresh1>0 and dpthresh2>0 and agi>=dpthresh1 then do;
                if agi<dpthresh2 then stded=max(0,stded-(dprate1/100)*(agi-dpthresh1));
                else stded=max(0,stded-(dprate1/100)*(dpthresh2-dpthresh1)-(dprate2/100)
                        *(agi-dpthresh2));
        end;

        /****************************************************************************
        * Potentially deductible fed income tax after any limitations (dedfit)      *
        *****************************************************************************/
        if dedfed=0 then do 
			dedfit=0 ;
			dedfit1=0 ;
			dedfit2=0 ;
		end ;
        else if dedfed=1 then do ;
                if limfdtype=0 then dedfit=max(taxf_S,0) ;
                else if limfdtype=1 and limfdpct=0 then dedfit=min(max(taxf_S,0), limfdamt) ;
                else if limfdtype=1 and limfdamt=0 then dedfit=(limfdpct/100)*max(taxf_S,0) ;
                else if limfdtype=1 and limfdpct*limfdamt>0 then
                        dedfit=min((limfdpct/100)*max(taxf_S,0),limfdamt);
                else if limfdtype=2 then do ;
                        if taxf_S < limfdamt then dedfit = min(max(taxf_S,0), limfdamt);
                        else if taxf_S>limfdamt and taxf_S<limfdamt2 then
                        	dedfit = limfdamt + (limfdpct/100)*(max(taxf_S,0)-limfdamt);
                        else dedfit=limfdamt2;
                end;
                else if limfdtype=3 then dedfit=min(1,(max(agi,0)/max(Fagi,1)))*max(taxf_S,0) ;
				else if limfdtype=4 then dedfit=min(max(taxf_S,0),.03*max(0,agi-max(stded,itemded-min(charity,max(0,(chlim/100)*agi))))) ;
				/* Separate filers. Note that there was no itemiz>1 when federal separate filing was allowed */
				if separate=1 then do ;
					if Fseparate=1 then do ;
						taxf1x=max(0,Fdtxliab_bc1 + (taxf-Fdtxliab_bc1-Fdtxliab_bc2)*
							Fdtxliab_bc1/max(Fdtxliab_bc1+Fdtxliab_bc2,1)) ;
						taxf2x=max(0,Fdtxliab_bc2 + (taxf-Fdtxliab_bc1-Fdtxliab_bc2)*
							Fdtxliab_bc2/max(Fdtxliab_bc1+Fdtxliab_bc2,1)) ;
						if Fsepfiler=1 then do ;
							taxf1=taxf1x ; taxf2=taxf2x ;
						end ;
						else do ;
							taxf1=max(0,taxf_S*(max(taxf1x,0)/max(max(taxf1x,0)+max(taxf2x,0),1))) ;
							taxf2=max(0,taxf_S*(max(taxf2x,0)/max(max(taxf1x,0)+max(taxf2x,0),1))) ;
						end ;
					end ;
					else do ;
						taxf1=max(0,taxf_S*(max(agi1,0)/max(max(agi1,0)+max(agi2,0),1))) ;
						taxf2=max(0,taxf_S*(max(agi2,0)/max(max(agi1,0)+max(agi2,0),1))) ;
					end ;
					/* primary taxpayer */
                	if limfdtype=0 then dedfit1=taxf1 ;
                	else if limfdtype=1 and limfdpct=0 then dedfit1=min(max(taxf1,0), limfdamt/2) ;
                	else if limfdtype=1 and limfdamt=0 then dedfit1=(limfdpct/100)*max(taxf1,0) ;
                	else if limfdtype=1 and limfdpct*limfdamt>0 then
                        dedfit1=min((limfdpct/100)*max(taxf1,0),limfdamt/2);
                	else if limfdtype=2 then do ;
                        if taxf1 < limfdamt/2 then dedfit1 = min(max(taxf1,0), limfdamt/2);
                        else if taxf1>=limfdamt/2 and taxf1<limfdamt2/2 then
                        	dedfit1 = limfdamt/2 + (limfdpct/100)*(max(taxf1,0)-limfdamt/2);
                        else dedfit1=limfdamt2/2;
                	end;
                	else if limfdtype=3 and Fedyear<1948 then dedfit1=min(1,(max(agi1,0)/max(Fagi1,1)))*max(taxf1,0) ;
					else if limfdtype=4 then do ;
						if itemded>stded then dedfit1 = 
							min(max(taxf1,0), .03*max(0,agi1-(itemded-min(charity,max(0,(chlim/100)*agi)))*
							(itemded1_S/max(itemded1_S+itemded2_S,1)))) ;
						else dedfit1 = min(max(taxf1,0), .03*
							max(0,agi1-min((pctstded/100)*agi1,maxstded))) ;
					end ;
					/* spouse */
                	if limfdtype=0 then dedfit2=taxf2 ;
                	else if limfdtype=1 and limfdpct=0 then dedfit2=min(max(taxf2,0), limfdamt/2) ;
                	else if limfdtype=1 and limfdamt=0 then dedfit2=(limfdpct/100)*max(taxf2,0) ;
                	else if limfdtype=1 and limfdpct*limfdamt>0 then
                        dedfit2=min((limfdpct/100)*max(taxf2,0),limfdamt/2);
                	else if limfdtype=2 then do ;
                        if taxf2 < limfdamt/2 then dedfit2 = min(max(taxf2,0), limfdamt/2);
                        else if taxf2>=limfdamt/2 and taxf2<limfdamt2/2 then
                        	dedfit2 = limfdamt/2 + (limfdpct/100)*(max(taxf2,0)-limfdamt/2);
                        else dedfit2=limfdamt2/2;
                	end;
                	else if limfdtype=3 and Fedyear<1948 then dedfit2=min(1,(max(agi2,0)/max(Fagi2,1)))*max(taxf2,0) ;
					else if limfdtype=4 then do ;
						if itemded>stded then dedfit2 = 
							min(max(taxf2,0), .03*max(0,agi2-(itemded-min(charity,max(0,(chlim/100)*agi)))*
								(itemded2_S/max(itemded1_S+itemded2_S,1)))) ;
						else dedfit2 = min(max(taxf2,0), .03*
							max(0,agi2-min((pctstded/100)*max(agi2,0),maxstded))) ;
					end ;
				end ;
        end;
        if asdfed=0 then itemded=itemded+dedfit;

		/*****************************************************************
		Itemized deductions if itemiz=4 and base ne fti
		The variables "sitdedallowed" and "busexallowed" are deductions for state income
		taxes and business expenses allowed after limitation.  These are used solely for
		allocating deductions across married separate filers.
		******************************************************************/
		/* NC 1989-present, SC 1985-present */ 
		if itemiz=4 and itemlim ne 2 and base ne "fti" then do ;
			if Fitemlost>0 then itemadd = min(max(0,Fitemded-Fitemlost-stded),max(0,((iunprotected-Fitemlost)/max(iunprotected,1))
					*(taxs_S + (Fsaleded=2)*max(salestax-taxs_S,0))));
			else itemadd = min(max(0,Fitemded-stded),max(0, taxs_S + (Fsaleded=2)*max(salestax-taxs_S,0)));
			itemded = Fitemded - Fitemlost - itemadd ;
			sitdedallowed=0 ;
   			if Fitemded>0 then busexallowed = max(0, (iunprotected-Fitemlost)/max(iunprotected,1))
				*max(0,busex+miscdedlim-.02*max(Fagi,0))*(busex/max(busex+miscdedlim,1)) ;
			else busexallowed=busex ;
			chlimbind = Fchlimbind ; 
		end ;
		/* MN 1987 - present */
		else if itemiz=4 and itemlim=2 and base ne "fti" then do ;
			itemadd = min(max(0,Fitemded-Fitemlost-stded),max(0, taxs_S + (Fsaleded=2)*max(salestax-taxs_S,0)));
			itemded = Fitemded - Fitemlost - itemadd ; 
			sitdedallowed=0 ;
   			if Fitemded>0 then busexallowed = max(0, (iunprotected-Fitemlost)/max(iunprotected,1))
				*max(0,busex+miscdedlim-.02*max(Fagi,0))*(busex/max(busex+miscdedlim,1)) ;
			else busexallowed=busex ;
			chlimbind = Fchlimbind ;
		end ;


		/******************************************************************
        *   State itemized deduction limitation: identical to federal     *
        *******************************************************************
        State itemized deductions equal federal, except that if
        state income tax is not deductible, the portion of the state income
        tax that is effectively deductible at the federal level is subtracted. 
		The variables "sitdedallowed" and "busexallowed" are deductions for state income
		taxes and business expenses allowed after limitation.  These are used solely for
		allocating deductions across married separate filers.
		********************************************************************/

       	else if itemlim=1 or itemlim>=50 then do ;
			itemded = max(0, itemded - Fitemlost +
            	Fitemlost*(sitded=0)*(taxs_S + (Fsaleded=2)*max(salestax-taxs_S,0) )/ max(iunprotected,1));
   			busexallowed = max(0, (iunprotected-Fitemlost)/max(iunprotected,1))
				*max(0,busex+miscdedlim-.02*max(Fagi,0))*(busex/max(busex+miscdedlim,1)) ;
			sitdedallowed = sitded*taxs_S*max(0, (iunprotected-Fitemlost)/max(iunprotected,1)) ;
		end ;

        /* state itemized deductions equal federal, except full amount of
           state income tax is subtracted, and not itemiz=4 (Missouri 1991-1992) */
        else if itemlim=2 then do ;
			itemded = max(0, itemded-Fitemlost);
			sitdedallowed=0 ;
   			busexallowed = max(0, (iunprotected-Fitemlost)/max(iunprotected,1))
				*max(0,busex+miscdedlim-.02*max(Fagi,0))*(busex/max(busex+miscdedlim,1)) ;
		end ;

        /************************************************
        *    State itemized deduction limitation,       *
        *    same as fed but different thresholds       *
        *************************************************/
        else if idphthresh>0 and agi>idphthresh then do;
                iprotecteds=medded*max(0, medexp-(Fmedded/100)*agi)
                + invint + max(casualty-(Fcasdedlim/100)*agi-100,0);
                iunprotecteds=itemded-iprotecteds;
				itemlosts=min(.8*(1-(1/3)*(Fidphrate=2)-(2/3)*(Fidphrate=3))*iunprotecteds,
					(Fidphrate/100)*(agi-idphthresh));
                itemded=itemded-itemlosts;
				sitdedallowed = sitded*taxs_S*max(0, (iunprotecteds-itemlosts)/max(iunprotecteds,1)) ;
   				busexallowed = max(0, (iunprotecteds-itemlosts)/max(iunprotecteds,1))
					*max(0,busex+miscdedlim-.02*agi)*(busex/max(busex+miscdedlim,1)) ;
        end;

		/*******************************************************
		* Allowable itemized deduction for businesss expenses  *
		* and state income tax, all other cases				   *
		********************************************************/
		else do ;
			sitdedallowed = sitded*taxs_S ;
			if itemiz>0 and Fbusexded=1 then 
				busexallowed = max(0,busex+miscdedlim-.02*max(Fagi,0))*(busex/max(busex+miscdedlim,1)) ;
			else busexallowed = busex ;
		end; 

        /************************************************************************* 
		* Flat-rate credit for itemized deductions. WI is only state where this  *
        * applies, so code is tailored to that (itemcred)                        *
		**************************************************************************/
        if icredrate>0 then do ;
                itemded=0;
                itemcred = (icredrate/100)*max(0, 
                        (charded*min(charity,max(0,(chlim/100)*agi)) + intded*(intpaid+invint)
                        + (medded=1)*max(0,medexp-(Fmedded/100)*max(Fagi,0))) - stded);
        end;
        else itemcred=0;


        /**************************************************************
        * State retirement income exclusions                          *
        * retexamt = maximum amount of exclusion                      *
        * agequal = number of people old enough to qualify for credit *
        ***************************************************************/
        if filertype="m" then agequal=((agex>=retexage)+(agespx>=retexage))/2 ;
        else if (filertype="s" or filertype="h") then agequal=(agex>=retexage) ;
        if (retextype ne 1) and ((agex>=retexage) or (agespx>=retexage)) then do;
                if retextype=0 then retexamt=pension*agequal;
                else if retextype=2 then retexamt=min(pension,retex*agequal);
                else if retextype=3 then retexamt=min(pension+div+int+rentinc,retex*agequal);
                else if retextype=4 then retexamt=min(pension+ssben,retex*agequal);
                else if retextype=5 then retexamt=min(pension, max(0,max(0,retex-ssben)*agequal));
                else if retextype=6 then retexamt=min(max(agi,0), retex*agequal);
                else if retextype=7 then retexamt=min(max(agi,0), max(0,retex-ssben)*agequal);
                else if retextype=9 then retexamt=min(pension+div+ltcg+int+rentinc,retex*agequal);
                else if retextype=11 then retexamt=(retph1/100)*min(pension,retex*agequal);
                else if retextype=13 then retexamt=min(int+div,retex*agequal);
				else if retextype=17 then do ;
					retexamt=min(max(agi,0), retex*agequal);
					retph2=retph1+retexamt/.5 ;
				end ;
				else if retextype=18 and stateyear-agex>=1939 and agi>=(lowph1+lowphdep*deps) then do ;
					retexamt=min(max(agi,0), retex*agequal);
					retph2=retph1+retexamt ;
				end ;
                else retexamt=0;

                if retexamt>0 and (retph1>0 or retph2>0) then do;
                     if retph1=retph2 and agi>=retph1 then retexamt=0;
                     else if agi>=retph1 then
                     retexamt=max(0,retexamt-((agi-retph1)/(retph2-retph1))*retexamt);
                end;

				/* married filing separately */
				if separate=1 then do ;
					agequal1 = (agex>=retexage) ;
					agequal2 = (agespx>=retexage) ;
			        if (retextype ne 1) and (agex>=retexage) then do;
		                if retextype=0 then retexamt1=pension1*agequal1;
        	        	else if retextype=2 then retexamt1=min(pension1,retex/2)*agequal1;
            	    	else if retextype=3 then retexamt1=min(pension1+div1+int1+rentinc1,retex/2)*agequal1;
                		else if retextype=4 then retexamt1=min(pension1+ssben1,retex/2)*agequal1;
                		else if retextype=5 then retexamt1=min(pension1, max(0,max(0,(retex/2)-ssben1)))*agequal1;
	                	else if retextype=6 then retexamt1=min(max(agi1,0), retex/2)*agequal1;
	                	else if retextype=7 then retexamt1=min(max(agi1,0), max(0,retex/2-ssben1))*agequal1;
	                	else if retextype=9 then retexamt1=min(pension1+div1+ltcg1+int1+rentinc1,retex/2)*agequal1;
	                	else if retextype=11 then retexamt1=(retph1/100)*min(pension1,retex/2)*agequal1;
	                	else if retextype=13 then retexamt1=min(int1+div1,retex/2)*agequal1;
	                	else retexamt1=0;
					end ;
					else retexamt1=0 ;
			        if (retextype ne 1) and (agespx>=retexage) then do;
		                if retextype=0 then retexamt2=pension2*agequal2;
        	        	else if retextype=2 then retexamt2=min(pension2,retex/2)*agequal2;
            	    	else if retextype=3 then retexamt2=min(pension2+div2+int2+rentinc2,retex/2)*agequal2;
                		else if retextype=4 then retexamt2=min(pension2+ssben2,retex/2)*agequal2;
                		else if retextype=5 then retexamt2=min(pension2, max(0,max(0,(retex/2)-ssben2)))*agequal2;
	                	else if retextype=6 then retexamt2=min(max(agi2,0), retex/2)*agequal2;
	                	else if retextype=7 then retexamt2=min(max(agi2,0), max(0,retex/2-ssben2))*agequal2;
	                	else if retextype=9 then retexamt2=min(pension2+div2+ltcg2+int2+rentinc2,retex/2)*agequal2;
	                	else if retextype=11 then retexamt2=(retph1/100)*min(pension2,retex/2)*agequal2;
	                	else if retextype=13 then retexamt2=min(int2+div2,retex/2)*agequal2;
	                	else retexamt2=0;
					end ;
					else retexamt2=0 ;
					if statename="mo" then do ;
						retexamt=retexamt1+retexamt2 ;
	                	if retexamt>0 and (retph1>0 or retph2>0) then do;
    	                	if retph1=retph2 and agi>=retph1 then retexamt=0;
	                    	else if agi>=retph1 then
		                	retexamt=max(0,retexamt -((agi-retph1)/(retph2-retph1))*retexamt);
                		end;
						retexamt1=retexamt*max(agi1,0)/max(max(agi1,0)+max(agi2,0),1) ;
						retexamt2=retexamt*max(agi2,0)/max(max(agi1,0)+max(agi2,0),1) ;
					end ;	
					else if statename="mt" then do ;
	                	if retexamt1>0 and (retph1>0 or retph2>0) then do;
	                    	if agi1>=retph1/2 then
		                	retexamt1=max(0,retexamt1-((agi1-retph1/2)/((retph2/2)-(retph1/2)))*retexamt1);
                		end;
	                	if retexamt2>0 and (retph1>0 or retph2>0) then do;
	                    	if agi2>=retph1/2 then
		                	retexamt2=max(0,retexamt2-((agi2-retph1/2)/((retph2/2)-(retph1/2)))*retexamt2);
                		end;						
					end ;
				end ;
        end;
        else do ;
			retexamt=0;
			retexamt1=0;
			retexamt2=0;
		end ;


        /******************************************************************
        * Low-income exemptions                                           *
        * lowexamt = value of low-income exemption                        *
        * Note: low-income credits and no-tax floors are calculated later *
        * in credit section of program                                    *
        *******************************************************************/
		lowexamt=0 ;
        if (lowtype=1 or lowtype=5 or lowtype=10 or lowtype=15)
                and (agi<(lowph2+lowphdep*deps) or lowph2<lowph1)
                and (agex>lowminage or agespx>lowminage)
                then do;
                if filertype="m" then agequal=((agex>=lowminage)+(agespx>=lowminage))/2 ;
                else if (filertype="s" or filertype="h") then agequal=(agex>=lowminage) ;
                if lowtype=1 then do;
						if lowph2>=lowph1 then do ;
                        	if agi<lowph1 then lowexamt=(agequal*low)+(agenum*loweldamt);
                        	else if (lowph1 ne lowph2) then
                                lowexamt=((agequal*low)+(agenum*loweldamt))
                                *(1-((agi-lowph1)/(lowph2-lowph1)));
                        	else lowexamt=0;
						end ;
						else if lowph2<lowph1 then do ;
	                        if agi>=lowph1 then lowexamt=low;
	                        else if agi>=lowph2 then lowexamt=low*((agi-lowph1)/(lowph1-lowph2));
						end ;
						if separate=1 then do ;
							lowexamt1=lowexamt/2 ;
							lowexamt2=lowexamt/2 ;
						end ;
                end;
                else if lowtype=5 then do;
                        if agi<lowph1 then lowexamt=max(0,min(pension+ssagi,low)) ;
                        else if (lowph1 ne lowph2) then
                                lowexamt=max(0,min(pension+ssagi,low))*
                                (1-((agi-lowph1)/(lowph2-lowph1)));
                        else lowexamt=0;
						lowexamt1=0 ; lowexamt2=0 ;
                end;
                else if lowtype=10 then do;
                        if agi<lowph1+(deps*lowphdep)
                                then lowexamt=max(0,min(labinc,lowph1+(deps*lowphdep)));
                        else lowexamt=0;
						if separate=1 then do ;
							lowexamt1=min(1,(labinc1/max(labinc1+labinc2,1)))*lowexamt ;
							lowexamt2=(1-min(1,(labinc1/max(labinc1+labinc2,1))))*lowexamt ;
						end; 
                end;
                else if lowtype=15 then do;
                        if Fagi<lowph1 then lowexamt=agequal*low;
                        else lowexamt=0;
						lowexamt1=0 ; lowexamt2=0 ;
                end;
        end;
        else do ;
			lowexamt=0;
			lowexamt1=0;
			lowexamt2=0;
		end ;
		/* New low-income dependent exemption in Alabama, starting 2007 */
		if lowtype = 24 then do ;
			if Fagi<lowph1 then lowexamt=deps*low ;
			else if Fagi<lowph2 then lowexamt=deps*lowdepamt ;
		end ;
		/* New low-income exemption in New Mexico starting 2006 */
		if xtaxtype = "lowexempt" then do ;
			if agi<xb1 then lowexamt = lowexamt + xexpercap*(1+(filertype="m")+deps) ;
			else lowexamt = lowexamt + (1+(filertype="m")+deps)*max(0, xexpercap - (xr1/100)*(agi-xb1)) ;
		end ;

        /************************************************************
        * Miscellaneous state exemptions and deductions (miscex)    *
        *************************************************************/
        if miscextype>0 then do;
                if miscextype=1 then miscex=min(int,miscexamt*agenum);
                else if miscextype=2 then miscex=
                        min(max(0,int+div+ltcg*(1-(cgexpct/100))+othcg-retexamt),
                        miscexamt*agenum);
                else if miscextype=3 then miscex=min(max(0,pension+ssagi-retexamt),
                        miscexamt*agenum);
                else if miscextype=4 then miscex=
                        min(pension,((agex<60)+(filertype="m")*(agespx<60))*miscexamt);
                else if miscextype=5 then miscex=
                        min(pension,((agex<65)+(filertype="m")*(agespx<65))*miscexamt);
                else if miscextype=6 then miscex=max(0, min(miscexamt, pension1)*(agex<65) + 
							min(miscexamt, pension2)*(agespx<65) - .5*max(0,agi-retph1)) ;
                else if miscextype=9 and deps>0 then miscex=miscexamt;
                else if (miscextype=11 or miscextype=12)
                        and ((age>61 and age<65) or (agesp>61 and agesp<65)) then do;
                        if miscextype=11 then miscex=
                                min(max(agi,0),max(0,((age>61)*(age<65)+(agesp>61)*(agesp<65))*miscexamt-ssben));
                        else if miscextype=12 then miscex=
                                min(max(agi,0),((age>61)*(age<65)+(agesp>61)*(agesp<65))*miscexamt);
                end;
				else if miscextype=15 and agi<40000 then miscex=miscexamt*agenum ;
				else if miscextype=17 and agi>=(lowph1+lowphdep*deps) then do ;
					if stateyear-age<1939 then miscex=min(max(agi,0), retex*agequal);
					else miscex=0 ;
					if stateyear=2004 then miscex=miscex+
						min(max(agi,0),((age>63)*(age<65)+(agesp>63)*(agesp<65))*miscexamt);
					else if stateyear=2005 then miscex=miscex+
						min(max(agi,0),((age=64)+(agesp=64))*miscexamt);
				end ;
				else if miscextype=18 then do;
                	if agi<miscexamt
                    	then miscex=max(0,min(labinc,miscexamt));
                    else lowexamt=0;
					if separate=1 then do ;
						lowexamt1=min(1,(labinc1/max(labinc1+labinc2,1)))*lowexamt ;
						lowexamt2=(1-min(1,(labinc1/max(labinc1+labinc2,1))))*lowexamt ;
					end; 
                end;
                else miscex=0;
				/* re-calculate for separate filers: 1 (mt), 4 (de), 11 (va), 12 (va) */
				if separate=1 then do ;
	                if miscextype=1 then do ;
						miscex1=min(int1,miscexamt*(agex>=65));
						miscex2=min(int2,miscexamt*(agespx>=65));
					end ;
                	else if miscextype=4 then do ;
						miscex1=min(pension1,(agex<60)*miscexamt);
						miscex2=min(pension2,(agespx<60)*miscexamt);
					end ;
	                else if (miscextype=11 or miscextype=12) then do ;
	                        if (age>61 and age<65) then do;
	                        	if miscextype=11 then miscex1=
	                                min(max(agi1,0),max(0,((age>61)*(age<65))*miscexamt-ssben1));
	                        	else if miscextype=12 then miscex1=
	                                min(max(agi1,0),((age>61)*(age<65))*miscexamt);
							end ;
							else miscex1=0 ;
	                        if (agesp>61 and agesp<65) then do;
	                        	if miscextype=11 then miscex2=
	                                min(max(agi2,0),max(0,((agesp>61)*(agesp<65))*miscexamt-ssben2));
	                        	else if miscextype=12 then miscex2=
	                                min(max(agi2,0),((agesp>61)*(agesp<65))*miscexamt);
							end ;
							else miscex2=0 ;
	                end;
					else do ;
						miscex1=0 ; miscex2=0 ;
					end ;
				end ;
				else do ;
					miscex1=0 ; miscex2=0 ;
				end ;

        end;
        else do ;
			miscex=0; miscex1=0 ; miscex2=0 ;
		end ;
        /* State deduction for two-earner couples (MD) */
        if mardedtype=2 and filertype="m"
                then miscex=miscex 
				+ min(max(0,labinc1+.5*(max(agi,0)-labinc1)),max(0,labinc2+.5*(max(agi,0)-labinc2)),mardedlim);

        /************************************************************************
        * State taxable income for states starting with a gross measure of		*
		* income, except for married filing separately							*
		* StiYI = state taxable income if itemizing								*
		* StiNI = state taxable if not itemizing								*
        *************************************************************************/
		if base ne "fti" then do ;
			/* Itemizers */
        	StiYI=max(0,agi-exempt-max(itemded-zba,0)-kcareadj-retexamt-lowexamt-miscex-asdfed*dedfit);
				/**************************************************************
				* Louisiana limitation of excess itemized deductions		  *
				***************************************************************/
				if itemlim >=50 then do ;
        			StiYI=max(0,agi-exempt-(itemlim/100)*max(itemded-zba,0)-kcareadj-retexamt-lowexamt
						-miscex-asdfed*dedfit);
					itemded = itemded - (1-(itemlim/100))*max(itemded-zba,0) ;
				end ;
			/* Non-itemizers */
		    StiNI=max(0,agi-SNIcharded-exempt-stded-kcareadj-retexamt-lowexamt-miscex-asdfed*dedfit);
		end;

        /*********************************************************
        * State taxable income for each spouse filing separately *
        * Sti1YI = 1st spouse's taxable income if itemizing      *
        * Sti2YI = 2nd spouse's taxable income if itemizing      *
		* Sti1NI = 1st spouse's taxable inncome if not itemizing *
		* Sti2NI = 2nd spouse's taxable income if not itemizing	 *
		* Note: exemptions are not phased-out in any states      *
		* where separate filing is advantageous.				 *
		* It's necessary to calculate tax liability with and	 *
		* without itemizing because in many states, separate     *
		* filers can allocate itemized deductions however they   *
		* want but must split standard deduction evenly          * 		
        **********************************************************/
        if separate=1 then do;
			if agi1>=agi2 then do ;
				deps1=deps ; deps2=0 ;
			end;
			else do ;
				deps1=0 ; deps2=deps ;
			end ;

			/* standard deductions for separate filers */
			if stdalloc=0 then do ;
		       	minsd1 = minstded/2 + (minstded_d * deps1) + (minstded_a * (agex>=65)) ;
 	       	   	maxsd1 = maxstded/2 + (maxstded_d * deps1) + (maxstded_a * (agex>=65)) ;
		       	minsd2 = minstded/2 + (minstded_d * deps2) + (minstded_a * (agespx>=65)) ;
 	       	   	maxsd2 = maxstded/2 + (maxstded_d * deps2) + (maxstded_a * (agespx>=65)) ;
 	       		if pctstded=0 then do ;
					stded1 = maxsd/2;
					stded2 = maxsd/2;
				end ;
	       		else do ;
					stded1=min(maxsd1,max((pctstded/100)*agi1,minsd1));
					stded2=min(maxsd2,max((pctstded/100)*agi2,minsd2));
				end ;
			end ;
			else if stdalloc=1 then do ;
		       	minsd1 = minstded/2 + (minstded_d * deps1) + (minstded_a * (agex>=65)) ;
 	       	   	maxsd1 = maxstded + (maxstded_d * deps1) + (maxstded_a * (agex>=65)) ;
		       	minsd2 = minstded/2 + (minstded_d * deps2) + (minstded_a * (agespx>=65)) ;
 	       	   	maxsd2 = maxstded + (maxstded_d * deps2) + (maxstded_a * (agespx>=65)) ;
 	       		if pctstded=0 then do ;
					stded1 = maxsd;
					stded2 = maxsd;
				end ;
	       		else do ;
					stded1=min(maxsd1,max((pctstded/100)*agi1,minsd1));
					stded2=min(maxsd2,max((pctstded/100)*agi2,minsd2));
				end ;
			end ; 
			else if stdalloc=3 then do ;
				stded1 = stded*max(agi1,0)/max(max(agi1,0)+max(agi2,0),1) ;
				stded2 = stded*max(agi2,0)/max(max(agi1,0)+max(agi2,0),1) ;
			end ;
			else do ;
				stded1=0 ;
				stded2=0 ;
			end ;

			/* non-discretionary exemptions for separate filers */
			if exalloc=0 then do ;
				exemptND1 = expercap + deps1*(expercap + ex_dep) + (agex>=65)*ex_age ;
				exemptND2 = expercap + deps2*(expercap + ex_dep) + (agespx>=65)*ex_age ;
			end ;
			else if exalloc=1 then do ;
				exemptND1 = expercap + (agex>=65)*ex_age ;
				exemptND2 = expercap + (agespx>=65)*ex_age ;				
			end ;
			else if exalloc=2 then do ;
				exemptND1 = exreturn/2 + expercap + deps1*(expercap + ex_dep) + (agex>=65)*ex_age ;
				exemptND2 = exreturn/2 + expercap + deps2*(expercap + ex_dep) + (agespx>=65)*ex_age ;				
			end ;
			else if exalloc=3 then do ;
				exemptND1 = exempt*max(agi1,0)/max(max(agi1,0)+max(agi2,0),1) ; 
				exemptND2 = exempt*max(agi2,0)/max(max(agi1,0)+max(agi2,0),1) ;  
			end ;
			else if exalloc=4 then do ;
				exemptND1 = 0 ; exemptND2 = 0 ;
			end ;
			else if exalloc=5 then do ;
				if agi1>=agi2 then do ;
					exemptND1 = (2/3)*exreturn + deps*ex_dep + (agex>=65)*ex_age ;
					exemptND2 = (1/3)*exreturn + (agespx>=65)*ex_age ;		
				end ;
				else do ;
					exemptND1 = (1/3)*exreturn + (agex>=65)*ex_age ;
					exemptND2 = (2/3)*exreturn + deps*ex_dep + (agespx>=65)*ex_age ;		
				end ;
			end; 
			else if exalloc=6 then do ;
				exemptND1 = (1/2)*(exreturn-300) + deps1*ex_dep + (agex>=65)*ex_age ;
				exemptND2 = (1/2)*(exreturn-300) + deps2*ex_dep + (agespx>=65)*ex_age ;
			end ;
			else if exalloc=7 then do ;
				exemptND1 = (1/2)*(exreturn) + (agex>=65)*ex_age ;
				exemptND2 = (1/2)*(exreturn) + (agespx>=65)*ex_age ;				
			end ;

			/* Discretionary exemptions and non-itemizer charitable deductions for separate filers */
			exemptDISC = max(exempt - exemptND1 - exemptND2 - (exalloc=6)*300 , 0) + SNIcharded ;

			/* State income tax deduction */
			sitded1 = sitdedallowed*min(1,max(0,taxs1_S/max(taxs1_S+taxs2_S,1))) ;
			sitded2 = sitdedallowed*(1-min(1,max(0,taxs1_S/max(taxs1_S+taxs2_S,1)))) ;

			/* Other non-discretionary deductions: dedfit, ssded, retexamt, miscex */

			/* itemized deductions */
			if itemalloc=1 then do ;
				itemdedND1 = min(1,max(0,(max(agi1,0)/max(max(agi1,0)+max(agi2,0),1))))*itemded ;
				itemdedND2 = (1-min(1,max(0,(max(agi1,0)/max(max(agi1,0)+max(agi2,0),1)))))*itemded ;
				itemdedDISC=0 ;
			end ;
			else do ;
				itemdedND1 = sitded1 + dedfit1*(asdfed=0) + ssded1 ;
				itemdedND2 = sitded2 + dedfit2*(asdfed=0) + ssded2 ;
				itemdedDISC = max(0, itemded - sitdedallowed - (dedfit1+dedfit2)*(asdfed=0) - (ssded1+ssded2)) ;
			end ;

			/* taxable income subtracting only non-discretionary deductions */

			/* non-itemizers */
				stiNIND1 = max(0, agi1 - exemptND1 - stded1 - dedfit1*(asdfed=1) 
					- retexamt1 - (lowexamt/2) - miscex1) ;
				stiNIND2 = max(0, agi2 - exemptND2 - stded2 - dedfit2*(asdfed=1) 
					- retexamt2 - (lowexamt/2) - miscex2) ;

			/* itemizers */
				stiYIND1 = max(0, agi1 - exemptND1 - itemdedND1 - dedfit1*(asdfed=1) 
					- retexamt1 - (lowexamt/2) - miscex1) ;
				stiYIND2 = max(0, agi2 - exemptND2 - itemdedND2 - dedfit2*(asdfed=1) 
					- retexamt2 - (lowexamt/2)- miscex2) ;

			/* allocate discretionary deductions */
			/* non-itemizers */
			if stiNIND1>=stiNIND2 then do ;
				dedDISCni1=min(kcareadj+exemptDISC+stded*(stdalloc=2)
					+min((pctstded/100)*max(agi1,0),stded)*(stdalloc=4),stiNIND1-stiNIND2);
				dedDISCni2=(stdalloc=4)*(stded+min(exemptDISC,stiNIND1-stiNIND2)-dedDISCni1) ;
				dedSPLITni=max(0,kcareadj+exemptDISC+stded*((stdalloc=2)+(stdalloc=4))-dedDISCni1-dedDISCni2)/2 ;
			end ;
			else do ;
				dedDISCni2=min(kcareadj+exemptDISC+stded*(stdalloc=2)
					+min((pctstded/100)*max(agi1,0),stded)*(stdalloc=4),stiNIND2-stiNIND1);
				dedDISCni1=(stdalloc=4)*(stded+min(exemptDISC,stiNIND2-stiNIND1)-dedDISCni2) ;
				dedSPLITni=max(0,kcareadj+exemptDISC+stded*((stdalloc=2)+(stdalloc=4))-dedDISCni1-dedDISCni2)/2 ;
			end ;
			/* itemizers */
			if stiYIND1>=stiYIND2 then do ;
				dedDISCyi1=min(kcareadj+exemptDISC+itemdedDISC,stiNIND1-stiNIND2);
				dedDISCyi2=0 ;
				dedSPLITyi=max(0,kcareadj+exemptDISC+itemdedDISC-dedDISCyi1-dedDISCyi2)/2 ;
			end ;
			else do ;
				dedDISCyi2=min(kcareadj+exemptDISC+itemdedDISC,stiNIND2-stiNIND1);
				dedDISCyi1=0 ;
				dedSPLITyi=max(0,kcareadj+exemptDISC+itemdedDISC-dedDISCyi1-dedDISCyi2)/2 ;
			end ; 
			itemded1 = itemdedND1 + ((dedDISCyi1+dedSPLITyi)/max(dedDISCyi1+dedDISCyi2+dedSPLITyi*2,1))*itemdedDISC ;
			itemded2 = itemdedND2 + ((dedDISCyi2+dedSPLITyi)/max(dedDISCyi1+dedDISCyi2+dedSPLITyi*2,1))*itemdedDISC ;
			exempt1 = exemptND1 + ((dedDISCyi1+dedSPLITyi)/max(dedDISCyi1+dedDISCyi2+dedSPLITyi*2,1))*exemptDISC ;
			exempt2 = exemptND2 + ((dedDISCyi2+dedSPLITyi)/max(dedDISCyi1+dedDISCyi2+dedSPLITyi*2,1))*exemptDISC ;

			/* taxable income for married filing separately */
			stiNI1 = max(0, stiNIND1-dedDISCni1-dedSPLITni) ;
			stiNI2 = max(0, stiNIND2-dedDISCni2-dedSPLITni) ;
			stiYI1 = max(0, stiYIND1-dedDISCyi1-dedSPLITyi) ;
			stiYI2 = max(0, stiYIND2-dedDISCyi2-dedSPLITyi) ;
        end;

        /************************************************
		* State taxable income for						*
        * states that start with federal taxable income *
        *************************************************/
        if base="fti" then do;
			StiNI = max(FtiNI-dedfit*asdfed-retexamt-lowexamt-miscex,0);
			/* if state income tax is not deductible and subtraction of state income taxes from
				itemized deductions are allowed to push them below the standard deduction */
			if sitded=0 then do ;
				if Fitemlost>0 then itemded = max(0, Fitemded - Fitemlost
					-((iunprotected-Fitemlost)/max(iunprotected,1))*(taxs_S + (Fsaleded=2)*max(salestax-taxs_S,0) ));
				else itemded = max(0, Fitemded - (taxs_S + (Fsaleded=2)*max(salestax-taxs_S,0) ) ) ;
				StiYI = max(FtiYI + max(0, Fitemded - itemded)-dedfit-retexamt-lowexamt-miscex, 0) ;
			end ;
			/* if state income tax is deductible */
			else do ;
				itemded = Fitemded - Fitemlost ;
				StiYI = max(FtiYI-dedfit-retexamt-lowexamt-miscex, 0) ;
			end ;
			/* set other variables to be saved */
            ssagi=Fssagi;
            agi=Fagi;
			chlimbind = Fchlimbind ;
		end ;

        /**********************************************************************************
        * "Normal" state tax calculation                                                  *
        * StaxNORM = state tax liability before credits, normal calculation               *
        * SmtrNORM = statutory marginal rate in tax bracket, normal calculation 		  *
		* StaxNORMni = state tax liability if not itemizing, normal calculation			  *
		* StaxNORMyi = state tax liability if itemizing, normal calculation				  *
        * StaxNORM1, StaxNORM2 = normal tax liability each spouse filing separately       *
        * SmtrNORM1, SmtrNORM2 = marginal bracket rates for each spouse filing separately *
        ***********************************************************************************/
		/************************************************************
		*  Normal tax calculation for single, HoH, and joint filers *
		*************************************************************/

		/* non-itemizers */
        %bracketreader(StiNI, StaxNORMni, rate, bracket, bracknum) ;
		SmtrNORMni=brackmtr ;

		/* itemizers */
 		%bracketreader(StiYI, StaxNORMyi, rate, bracket, bracknum) ;
		SmtrNORMyi=brackmtr ;


		/********************************************
		New York state surtax starting in 2006
		*********************************************/
		if sptx2 = "surtax" and agi > sptxex2 then do ;
			StaxNORMni = StaxNORMni 
				+ max(0,(r5/100)*StiNI - StaxNORMni)*min(1,max(0,(agi-sptxex2)/(sptxrate2 - sptxex2))) ;
			StaxNORMyi = StaxNORMyi 
				+ max(0,(r5/100)*StiYI - StaxNORMyi)*min(1,max(0,(agi-sptxex2)/(sptxrate2 - sptxex2))) ;
		end ;

		/****************************************** 
		Determine itemization status 				
		*******************************************/
		if iteration=1 then do ;
			/* states with no constraints */
			if itemiz<2 then do ;
				if StaxNORMni <= StaxNORMyi then do ;
					itemizer_s=0 ;
					StaxNORM = StaxNORMni ;
					SmtrNORM = SmtrNORMni ;
					Sti = StiNI ;
				end ;
				else do ;
					itemizer_s=1 ;
					StaxNORM = StaxNORMyi ;
					SmtrNORM = SmtrNORMyi ;
					Sti = StiYI ;
				end ;	
			end ;
			/* states where itemization status must be the same as federal */
			else if itemiz=2 or itemiz=4 then do ;
				if Fitemizer_S=0 then do ;
					itemizer_s=0 ;
					StaxNORM = StaxNORMni ;
					SmtrNORM = SmtrNORMni ;
					Sti = StiNI ;
				end ;
				else if Fitemizer_S=1 then do ;
					itemizer_s=1 ;
					StaxNORM = StaxNORMyi ;
					SmtrNORM = SmtrNORMyi ;
					Sti = StiYI ;
				end ;
			end ;
			/* states where federal itemizers can choose state itemization status,
			   but federal non-itemizers must take state standard deduction */
			else if itemiz=3 then do ;
				if Fitemizer_S=0 then do ;
					itemizer_s=0 ;
					StaxNORM = StaxNORMni ;
					SmtrNORM = SmtrNORMni ;
					Sti = StiNI ;
				end ;
				else do ;
					if StaxNORMni <= StaxNORMyi then do ;
						itemizer_s=0 ;
						StaxNORM = StaxNORMni ;
						SmtrNORM = SmtrNORMni ;
						Sti = StiNI ;
					end ;
					else do ;
						itemizer_s=1 ;
						StaxNORM = StaxNORMyi ;
						SmtrNORM = SmtrNORMyi ;
						Sti = StiYI ;
					end ;
				end ;	
			end ;
			/* states where federal non-itemizers can choose state itemization status,
			   but federal itemizers must also itemize on state return */				
			else if itemiz=5 then do ;
				if Fitemizer_S=0 then do ;
					if StaxNORMni <= StaxNORMyi then do ;
						itemizer_s=0 ;
						StaxNORM = StaxNORMni ;
						SmtrNORM = SmtrNORMni ;
						Sti = StiNI ;
					end ;
					else do ;
						itemizer_s=1 ;
						StaxNORM = StaxNORMyi ;
						SmtrNORM = SmtrNORMyi ;
						Sti = StiYI ;
					end ;
				end ;	
				else do ;
					itemizer_s=1 ;
					StaxNORM = StaxNORMyi ;
					SmtrNORM = SmtrNORMyi ;
					Sti = StiYI ;
				end ;
			end ;
		end ;
		else do ;
			itemizer_s = itemizer_sCONSTANT ;
			if itemizer_s=0 then do ;
				StaxNORM = StaxNORMni ;
				SmtrNORM = SmtrNORMni ;
				Sti = StiNI ;
			end ;
			else do ;
				StaxNORM = StaxNORMyi ;
				SmtrNORM = SmtrNORMyi ;
				Sti = StiYI ;
			end ;
		end ;

		/* Choice between New Jersey property tax deduction and credit */
		/* Note: credit is added into lowcredref later */
		if cbtype=17 and (income>xcbthresh5 or agenum>0) and (StaxNORMni-StaxNORMyi<cbincval2) then do ;
			itemizer_s=0 ;
			StaxNORM = StaxNORMni ;
			SmtrNORM = SmtrNORMni ;
			Sti = StiNI ;				
		end ;

		/********************************************************
		*  Normal tax calculation for married filing separately *
		*********************************************************/
       	if separate=1 then do;
			/* non-itemizers */
           	%bracketreader(StiNI1, StaxNORMni1, rate, bracket, bracknum) ;
           	SmtrNORMni1=brackmtr ;
           	%bracketreader(StiNI2, StaxNORMni2, rate, bracket, bracknum) ;
           	SmtrNORMni2=brackmtr ;
			/* itemizers */
           	%bracketreader(StiYI1, StaxNORMyi1, rate, bracket, bracknum) ;
           	SmtrNORMyi1=brackmtr ;
           	%bracketreader(StiYI2, StaxNORMyi2, rate, bracket, bracknum) ;
           	SmtrNORMyi2=brackmtr ;

			/****************************************** 
			Determine itemization status 				
			*******************************************/
			if iteration=1 then do ;
				/* states with no constraint on itemization status */
				if itemiz<2 then do ;
					if (StaxNORMni1+StaxNORMni2) <= (StaxNORMyi1+StaxNORMyi2) then do ;
						itemizerSEP=0 ;
						StaxNORM1 = StaxNORMni1 ;
						StaxNORM2 = StaxNORMni2 ;
						SmtrNORM1 = SmtrNORMni1 ;
						SmtrNORM2 = SmtrNORMni2 ;
						Sti1 = StiNI1 ;
						Sti2 = StiNI2 ;
					end ;
					else do ;
						itemizerSEP=1 ;
						StaxNORM1 = StaxNORMyi1 ;
						StaxNORM2 = StaxNORMyi2 ;
						SmtrNORM1 = SmtrNORMyi1 ;
						SmtrNORM2 = SmtrNORMyi2 ;
						Sti1 = StiYI1 ;
						Sti2 = StiYI2 ;
					end ;
				end ;
				/* states where itemization status must be the same as federal */
				else if itemiz=2 or itemiz=4 then do ;
					if Fitemizer_S=0 then do ;
						itemizerSEP=0 ;
						StaxNORM1 = StaxNORMni1 ;
						StaxNORM2 = StaxNORMni2 ;
						SmtrNORM1 = SmtrNORMni1 ;
						SmtrNORM2 = SmtrNORMni2 ;
						Sti1 = StiNI1 ;
						Sti2 = StiNI2 ;
					end ;
					else if Fitemizer_S=1 then do ;
						itemizerSEP=1 ;
						StaxNORM1 = StaxNORMyi1 ;
						StaxNORM2 = StaxNORMyi2 ;
						SmtrNORM1 = SmtrNORMyi1 ;
						SmtrNORM2 = SmtrNORMyi2 ;
						Sti1 = StiYI1 ;
						Sti2 = StiYI2 ;
					end ;
				end ;
				/* states where federal itemizers can choose state itemization status,
				   but federal non-itemizers must take state standard deduction */
				else if itemiz=3 then do ;
					if Fitemizer_S=0 then do ;
						itemizerSEP=0 ;
						StaxNORM1 = StaxNORMni1 ;
						StaxNORM2 = StaxNORMni2 ;
						SmtrNORM1 = SmtrNORMni1 ;
						SmtrNORM2 = SmtrNORMni2 ;
						Sti1 = StiNI1 ;
						Sti2 = StiNI2 ;
					end ;
					else do ;
						if (StaxNORMni1+StaxNORMni2) <= (StaxNORMyi1+StaxNORMyi2) then do ;
							itemizerSEP=0 ;
							StaxNORM1 = StaxNORMni1 ;
							StaxNORM2 = StaxNORMni2 ;
							SmtrNORM1 = SmtrNORMni1 ;
							SmtrNORM2 = SmtrNORMni2 ;
							Sti1 = StiNI1 ;
							Sti2 = StiNI2 ;
						end ;
						else do ;
							itemizerSEP=1 ;
							StaxNORM1 = StaxNORMyi1 ;
							StaxNORM2 = StaxNORMyi2 ;
							SmtrNORM1 = SmtrNORMyi1 ;
							SmtrNORM2 = SmtrNORMyi2 ;
							Sti1 = StiYI1 ;
							Sti2 = StiYI2 ;
						end ;
					end ;	
				end ;
				/* states where federal non-itemizers can choose state itemization status,
				   but federal itemizers must also itemize on state return */				
				else if itemiz=5 then do ;
					if Fitemizer_S=0 then do ;
						if (StaxNORMni1+StaxNORMni2) <= (StaxNORMyi1+StaxNORMyi2) then do ;
							itemizerSEP=0 ;
							StaxNORM1 = StaxNORMni1 ;
							StaxNORM2 = StaxNORMni2 ;
							SmtrNORM1 = SmtrNORMni1 ;
							SmtrNORM2 = SmtrNORMni2 ;
							Sti1 = StiNI1 ;
							Sti2 = StiNI2 ;
						end ;
						else do ;
							itemizerSEP=1 ;
							StaxNORM1 = StaxNORMyi1 ;
							StaxNORM2 = StaxNORMyi2 ;
							SmtrNORM1 = SmtrNORMyi1 ;
							SmtrNORM2 = SmtrNORMyi2 ;
							Sti1 = StiYI1 ;
							Sti2 = StiYI2 ;
						end ;
					end ;	
					else do ;
						itemizerSEP=1 ;
						StaxNORM1 = StaxNORMyi1 ;
						StaxNORM2 = StaxNORMyi2 ;
						SmtrNORM1 = SmtrNORMyi1 ;
						SmtrNORM2 = SmtrNORMyi2 ;
						Sti1 = StiYI1 ;
						Sti2 = StiYI2 ;
					end ;
				end ;
			end ;
			else do ;
				itemizerSEP = itemizerSEPCONSTANT ;
				if itemizerSEP=0 then do ;
					StaxNORM1 = StaxNORMni1 ;
					StaxNORM2 = StaxNORMni2 ;
					SmtrNORM1 = SmtrNORMni1 ;
					SmtrNORM2 = SmtrNORMni2 ;
					Sti1 = StiNI1 ;
					Sti2 = StiNI2 ;	
				end ;
				else do ;
					StaxNORM1 = StaxNORMyi1 ;
					StaxNORM2 = StaxNORMyi2 ;
					SmtrNORM1 = SmtrNORMyi1 ;
					SmtrNORM2 = SmtrNORMyi2 ;
					Sti1 = StiYI1 ;
					Sti2 = StiYI2 ;
				end ;
			end ;

				/* Virginia credit for two-earner married couples */
				if mardedtype=5 then do ;
					Sti1 = max(0, agi1-retexamt1-expercap-ex_age*(agex>=65), 
						agi2-retexamt2-expercap-ex_age*(agespx>=65),Sti/2) ;
					Sti2 = min(max(0,agi1-retexamt1-expercap-ex_age*(agex>=65)), 
						max(0,agi2-retexamt2-expercap-ex_age*(agespx>=65)),Sti/2) ;
	            	%bracketreader(Sti1, StaxNORM1, rate, bracket, bracknum) ;
	            	%bracketreader(Sti2, StaxNORM2, rate, bracket, bracknum) ;
					marcred = min(mardedlim, max(0, StaxNORM - StaxNORM1 - StaxNORM2)) ;
					StaxNORM = max(0, StaxNORM-marcred) ;
				end ;
        	end;
			/* Minnesota two-earner credit 2002- */
			if mardedtype=4 and filertype="m" then do ; 
				lowEI = min(nflabinc1+pension1+ssagi*(ssben1/max(ssben,1)),
					nflabinc2+pension2+ssagi*(ssben2/max(ssben,1))) ;
				if (lowEI>=mardedlim) and (Sti>=mardedpct) then do ;
					Sti1 = max(0,Sti-lowEI) ;
					Sti2 = max(0,lowEI) ;
            		%bracketreader(Sti1, StaxNORM1, xrate, xbracket, xbracknum) ;
            		SmtrNORM1=brackmtr ;
            		%bracketreader(Sti2, StaxNORM2, xrate, xbracket, xbracknum) ;
            		SmtrNORM2=brackmtr ;
					if StaxNORM1+StaxNORM2<StaxNORM then do ;
						StaxNORM=StaxNORM1+StaxNORM2 ;
						SmtrNORM=SmtrNORM1 ;
					end ;
				end ;
			end ;

        /*************************************************************
        * "Special" taxes on components of capital income (sptxliab) *
        **************************************************************/
        if sptx="cgtax" then sptxliab=(sptxrate/100)*max(0, ltcg+othcg-sptxex);
        else if sptx="dtax" then sptxliab=(sptxrate/100)*max(0, div-sptxex);
        else if sptx="ditax" then sptxliab=(sptxrate/100)*max(0, div+int-sptxex);
        else if sptx="dcgtax" then sptxliab=(sptxrate/100)*max(0, div+ltcg+othcg-sptxex);
        else if sptx="dcgitax" then sptxliab=(sptxrate/100)*max(0, div+ltcg+othcg+int-sptxex);
        else if sptx="dltax" then sptxliab=(sptxrate/100)*max(0, labinc+div-sptxex);
        else sptxliab=0;
			/* filing separately */
			if separate=1 then do ;
		        if sptx="cgtax" then sptxliab1=(sptxrate/100)*max(0, ltcg1+othcg1-sptxex/2);
		        else if sptx="dtax" then sptxliab1=(sptxrate/100)*max(0, div1-sptxex/2);
		        else if sptx="ditax" then sptxliab1=(sptxrate/100)*max(0, div1+int1-sptxex/2);
		        else if sptx="dcgtax" then sptxliab1=(sptxrate/100)*max(0, div1+ltcg1+othcg1-sptxex/2);
		        else if sptx="dcgitax" then sptxliab1=(sptxrate/100)*max(0, div1+ltcg1+othcg1+int1-sptxex/2);
		        else if sptx="dltax" then sptxliab1=(sptxrate/100)*max(0, labinc1+div1-sptxex/2);
		        else sptxliab1=0;
		        if sptx="cgtax" then sptxliab2=(sptxrate/100)*max(0, ltcg2+othcg2-sptxex/2);
		        else if sptx="dtax" then sptxliab2=(sptxrate/100)*max(0, div2-sptxex/2);
		        else if sptx="ditax" then sptxliab2=(sptxrate/100)*max(0, div2+int2-sptxex/2);
		        else if sptx="dcgtax" then sptxliab2=(sptxrate/100)*max(0, div2+ltcg2+othcg2-sptxex/2);
		        else if sptx="dcgitax" then sptxliab2=(sptxrate/100)*max(0, div2+ltcg2+othcg2+int2-sptxex/2);
		        else if sptx="dltax" then sptxliab2=(sptxrate/100)*max(0, labinc2+div2-sptxex/2);
		        else sptxliab2=0;
			end ;

        /*** Second "special" tax ***/
        if sptx2="cgtax" then sptx2liab=(sptxrate2/100)*max(0, ltcg+othcg-sptxex2);
        else if sptx2="ditax" then sptx2liab=(sptxrate2/100)*max(0, div+int-sptxex2);
        else sptx2liab=0;
			/* filing separately */
			if separate=1 then do ;
		        if sptx2="cgtax" then sptx2liab1=(sptxrate2/100)*max(0, ltcg1+othcg1-sptxex2/2);
		        else if sptx2="ditax" then sptx2liab1=(sptxrate2/100)*max(0, div1+int1-sptxex2/2);
		        else sptx2liab1=0;
		        if sptx2="cgtax" then sptx2liab2=(sptxrate2/100)*max(0, ltcg2+othcg2-sptxex2/2);
		        else if sptx2="ditax" then sptx2liab2=(sptxrate2/100)*max(0, div2+int2-sptxex2/2);
		        else sptx2liab2=0;
			end ;

        /**************************************************************************
        * State alternative maximum tax that is a % of                            *
        * federal liability before credits                                        *
        ***************************************************************************/
        if sptx="maxpctfd" then StaxMAXPCTFD=(sptxrate/100)*(Fdtxliab_bc_S + FtaxMIN_S + Famt_S) ;

        /*************************************************************************
        * State alternative capital gains tax calculations                       *
        **************************************************************************/
        /*************************************************************************
        *    cgmax1                                                              *
        *    Re-calculate normal tax excluding gains, tax gains at flat rate     *
        *    StaxALTCG is tax liability after alternative cap gains computation  *
        *    EXCG indicates excluding capital gains                              *
		*    Applied only in Hawaii, 1958-1981									 *
        **************************************************************************/
        if sptx="cgmax1" and
	        max(SmtrNORM,SmtrNORM1,SmtrNORM2)*(1-(cgexpct/100)) > sptxrate then do;
                StiEXCG = max(0, Sti - (1-(cgexpct/100))*ltcg);
                %bracketreader(StiEXCG, StaxEXCG, rate, bracket, bracknum) ;
                StaxALTCG = StaxEXCG + (sptxrate/100)*ltcg;
        end;
        /**************************************************************************
        *    cgmax2                                                               *
        *    A maximum rate is applied to gains. Portion of gains already taxed   *
        *    at lower rates remain taxed at lower rates.                          *
        *    Note: this only applies in 2 states, HI and AR, and in both states   *
        *    	it happens to begin to apply in the 6th bracket.                  *
        *    StaxALTCG is tax liability after alternative cap gains computation   *
        *    EXCG indicates excluding gains                                       *
        ***************************************************************************/
        else if sptx="cgmax2" and ltcg>0 and Sti>b6 then do;
        	if (Sti-(1-(cgexpct/100))*ltcg)>=b6 then do;
            	StiEXCG=max(0, Sti-(1-(cgexpct/100))*ltcg);
                %bracketreader(StiEXCG, StaxEXCG, rate, bracket, bracknum) ;
                StaxALTCG = StaxEXCG + (sptxrate/100)*ltcg*(1-(cgexpct/100));
            end;
            else if (Sti-(1-(cgexpct/100))*ltcg) < b6 then do;
            	%bracketreader(b6, Staxb6, rate, bracket, bracknum) ;
                StaxALTCG = Staxb6 + (sptxrate/100)*(Sti-b6) ;
            end;
            if separate=1 and (Sti1>b6 or Sti2>b6) then do;
            	StiEXCG1=max(0,Sti1-ltcg1*(1-(cgexpct/100)));
                StiEXCG2=max(0,Sti2-ltcg2*(1-(cgexpct/100)));
                if (Sti1-ltcg1)>=b6 then do;
                	%bracketreader(StiEXCG1, StaxEXCG1, rate, bracket, bracknum) ;
                    StaxALTCG1=StaxEXCG1+(sptxrate/100)*ltcg1*(1-(cgexpct/100));
                end;
                else if Sti1 > b6 and (Sti1-ltcg1)<b6 then do;
                	%bracketreader(b6, Staxb61, rate, bracket, bracknum) ;
                    StaxALTCG1=Staxb61+(sptxrate/100)*(Sti1-b6);
                end;
                else StaxALTCG1=StaxNORM1;
                if (Sti2-ltcg2)>=b6 then do;
                	%bracketreader(StiEXCG2, StaxEXCG2, rate, bracket, bracknum) ;
                    StaxALTCG2=StaxEXCG2+(sptxrate/100)*ltcg2*(1-(cgexpct/100));
                end;
                else if Sti2 > b6 and (Sti2-ltcg2)<b6 then do;
                	%bracketreader(b6, Staxb62, rate, bracket, bracknum) ;
                    StaxALTCG2=Staxb62+(sptxrate/100)*(Sti2-b6);
                end;
                else StaxALTCG2=StaxNORM2;
            end;
			else if separate=1 then do ;
				StaxALTCG1=StaxNORM1 ;
				StaxALTCG2=StaxNORM2 ;
			end ;
        end;
       /********************************************************************************
        *    cgmax5 (RI, 2001-present, replicates federal with different rates          *
        *    Gains taxed at reduced rates, with rate depending on which bracket(s)      *
        *    the gains would fall into in normal tax.                                   *
        *    StiEXCG = taxable income less long-term gains                              *
		*	 SCGa = LT gains taxed at lower rate										*
        *    StaxCGa = alt. tax on LT cap gains that would be taxed in lower bracket(s) *
		*    SCGb = LT gains taxed at higher rate										*
        *    StaxCGb = alt. tax on LT cap gains that would be taxed in 2nd bracket      *
        *********************************************************************************/
        else if (xtaxtype="cgmax5" and ltcg ne 0) then do;
                StiEXCG=max(0, Fti_S-ltcg);
                %bracketreader(StiEXCG, StaxEXCG, rate, bracket, bracknum) ;
				
                /* gains taxed at 1st CG rate */
                if StiEXCG < xb2 then do ;
					SCGa = max(0,min(Sti,xb2)-StiEXCG) ;
					StaxCGa=(xr1/100)*SCGa ;
				end ; 
                else do ;
					SCGa = 0;
					StaxCGa=0;
				end ;

                /* gains taxed at 2nd CG rate */
                SCGb = max(0,min(Sti,ltcg)-SCGa) ;
				StaxCGb = (xr2/100)*SCGb ;	

                /* tax liability with CG adjustment */
                StaxALTCG = StaxEXCG + StaxCGa + StaxCGb ;
        end;
		/* States without alternative capital gains calculations */
        else do ;
			StaxALTCG=StaxNORM;
			if separate=1 then do ;
				StaxALTCG1=StaxNORM1;
				StaxALTCG2=StaxNORM2;
			end ;
		end ;

        /**********************************************************
        * Calculate tax liability after "special" taxes (StaxASP) *
        ***********************************************************/
        if sptx="maxpctfd" then StaxASP=Min(StaxMAXPCTFD,StaxNORM);
        else if sptx="cgmax1" or sptx="cgmax2"
                then StaxASP = max(0,min(StaxALTCG,StaxNORM));
        else if sptx="none" then StaxASP=StaxNORM;
        else StaxASP = max(0, StaxNORM + sptxliab + sptx2liab) ;
			/* separate filers */
			if separate=1 then do ;
		       if sptx="cgmax1" or sptx="cgmax2" then do ;
	                StaxASP1 = max(0,min(StaxALTCG1,StaxNORM1));
					StaxASP2 = max(0,min(StaxALTCG2,StaxNORM2));
			   end ;
		       else if sptx="none" then do ;
					StaxASP1=max(0,StaxNORM1);
					StaxASP2=max(0,StaxNORM2);
			   end ;
		       else do ;
					StaxASP1 = max(0, StaxNORM1 + sptxliab1 + sptx2liab1) ;
					StaxASP2 = max(0, StaxNORM2 + sptxliab2 + sptx2liab2) ;
			   end ;
			end ;


        /**********************************************************
        * State minimum taxes                                     *
		* StaxTAMT = state tentative alternative minimum tax      *
        * StaxMIN =  state minimum tax liability                  *
		* 1 (ny), 5 (mn, ia), and 7 (ia) were used in 			  * 
		* separate-filing states		                          *
        ***********************************************************/
        if mintaxtype>0 then do;
	        if mintaxtype=1 then do; 
				StaxMIN=(mintaxrate/100)*max(0, Ftaxpref_S+Famtpref_S-mintaxex);
				StaxTAMT=0;
				if separate = 1 then do ;
					/* Minimum tax preferences for separate filers */
					/* 1970-75 */
		            if Fmintaxtype=1 then do ;
						taxpref1 = exltcg1 + otaxpref/2 ;
						taxpref2 = exltcg2 + otaxpref/2 ;
					end ;
		            /* 1976 */
                	else if Fmintaxtype=2 and Fedyear=1976 then do ;
						taxpref1 =
                       	exltcg1 + otaxpref/2
                        + max(0,min(itemded1/max(1,itemded1+itemded2),1))*(Fitemizer_S*max(0,min(Fagi-Fexempt,Fitemded)
						-(Fmedded>0)*max(0,medexp-(Fmedded/100)*max(Fagi,0))
                        -max(0,casualty-100)-.6*max(Fagi,0))) ;
						taxpref2 =
                       	exltcg2 + otaxpref/2
                        + max(0,min(itemded2/max(1,itemded1+itemded2),1))*(Fitemizer_S*max(0,min(Fagi-Fexempt,Fitemded)
						-(Fmedded>0)*max(0,medexp-(Fmedded/100)*max(Fagi,0))
                        -max(0,casualty-100)-.6*max(Fagi,0))) ;
					end ;
                	/* 1977-78 */
                	else if Fmintaxtype=2 and Fedyear>1976 then do ;
						taxpref1 =
                        exltcg1 + otaxpref/2 +
                        max(0,min(itemded1/max(1,itemded1+itemded2),1))*(Fitemizer_S*max(0,min(Fagi-exempt,Fitemded)
						-(Fmedded>0)*max(0,medexp-(Fmedded/100)*max(Fagi,0))
                        -max(0,casualty-100)-taxs_S-proptax-salestax-tax_nonincome_S-(statename="zz")*stinctax-.6*max(Fagi,0))) ;
						taxpref2 =
                        exltcg2 + otaxpref/2 +
                        max(0,min(itemded2/max(1,itemded1+itemded2),1))*(Fitemizer_S*max(0,min(Fagi-exempt,Fitemded)
						-(Fmedded>0)*max(0,medexp-(Fmedded/100)*max(Fagi,0))
                        -max(0,casualty-100)-taxs_S-proptax-salestax-tax_nonincome_S-(statename="zz")*stinctax-.6*max(Fagi,0))) ;
					end ;
                	/* 1979-82 */
                	else if Fmintaxtype=3 then do ;
						taxpref1 = otaxpref/2 ;
						taxpref2 = otaxpref/2 ;
					end ;
					/* AMT preferences for separate filers */
                	/* 1979-82 */
                	if (Famttype=1 or Famttype=2) then do;
						iprotected = 
							(Fmedded>0)*max(0,medexp-(Fmedded/100)*max(Fagi,0))
							+max(0,casualty-100)
							+taxs_S
                        	+proptax
							+salestax
							+tax_nonincome_S
							+(statename="zz")*stinctax ;
                        amtpref1 = exltcg1 + 
							max(0,min(itemded1/max(1,itemded1+itemded2),1))*Fitemizer_S*max(0,Fitemded-iprotected-.6*max(Fagi-iprotected,0)) ;
                        amtpref2 = exltcg2 + 
							max(0,min(itemded2/max(1,itemded1+itemded2),1))*Fitemizer_S*max(0,Fitemded-iprotected-.6*max(Fagi-iprotected,0)) ;
                	end;
                	/* 1983-86 */
                	else if famttype=3 then do;
                        amtpref1 = exltcg1 + min(div1, Fdivexamt/2) + otaxpref/2 ;
                        amtpref2 = exltcg2 + min(div2, Fdivexamt/2) + otaxpref/2 ;
                  	end;
					StaxMIN1=(mintaxrate/100)*max(0, taxpref1+amtpref1-mintaxex/2);
					StaxMIN2=(mintaxrate/100)*max(0, taxpref2+amtpref2-mintaxex/2);
					StaxTAMT1=0;
					StaxTAMT2=0;					
				end;
			end;
    	    else if mintaxtype=2 then do;
                amtiae=max(0,Ftaxpref_S+Famtpref_S-mintaxex) ;
                %bracketreader(amtiae, StaxMIN, xrate, xbracket, xbracknum) ;
				StaxTAMT=0;
        	end;
			else if mintaxtype=5 then do;
				StaxMIN=(mintaxrate/100)*(Famt_S+FtaxMIN_S) ;
				StaxTAMT=0;
			end;
        	else if mintaxtype=3 and Famt_S>0 then do ;

				if statename="wi" then amti = Famti_S - exltcg ;
 				else if statename="co" then amti = Famti_S - retexamt ;
				else if statename="mn" then amti = Famti_S + (stateyear=2002)*min(.01*agi,min(charity,max(0,(chlim/100)*agi))*Fitemizer_S) 
						+ (2003<=stateyear)*(stateyear<=2005)*min(.01*agi,min(charity,max(0,(chlim/100)*agi))*Fitemizer_S) ;
				else if statename="ca" then amti = max(0, Famti_S + (stateyear<2002)*charcg - max(1000000,businc+farminc+partscorp)) ;
				else amti = Famti_S ;

				if statename="ca" then amtexempt=max(0,xb1-(Famtexrate/100)*max(0,amti-xb2));
				else amtexempt=max(0,Famtex-(Famtexrate/100)*max(0,amti-Famtexth));

				amtiae = max(amti-amtexempt,0) ;
                StaxTAMT = (mintaxrate/100)*max(0,amtiae) ;
				StaxMIN = 0 ;
			end ;
        	else if (mintaxtype=4 or mintaxtype=6) and Famt_S>0 then do ;
				if statename="ct" then amti = max(0,Famti_S - (Fssagi-ssagi)) ;
				else amti = Famti_S ;
                amtexempt=max(0, Famtex-(Famtexrate/100)*max(0,amti-Famtexth));
                amtiae=max(0, amti-amtexempt);

                /* Calculate tamt */
                /* 1979-80, 82-96 */
                if (Famttype ne 2) and (Famttype ne 7) then do;
                        %bracketreader(amtiae, tamt, Famtrate, Famtbracket, Famtbrkn) ;
                end;
                /* 1981 */
                else if (Famttype=2) then do;
                        %bracketreader(amtiae, tamtA, Famtrate, Famtbracket, Famtbrkn) ;
                        Famtr3=25;
                        amtEXCG=max(0,amtiae-Fexltcg);
                        %bracketreader(amtEXCG, tamtB, Famtrate, Famtbracket, Famtbrkn) ;
                        Famtr3=20;
                        tamt=min(tamtA, tamtB+.2*Fexltcg);
                end;
                /* 1997-present */
                else if (Famttype=7) then do;
                	%bracketreader(amtiae,tamtnorm, Famtrate, Famtbracket, Famtbrkn) ;

					/* For those subject to alternative capital gains computation */
					if (Fxtaxtype="cgmax5" or Fxtaxtype="cgmax6") and (ltcg+div) > 0 then do;
                		amtiaeEXCG=max(0, amtiae-min(amtiae,ltcg+(Fxtaxtype="cgmax6")*div));
                		%bracketreader(amtiaeEXCG, tamtEXCG, Famtrate, Famtbracket, Famtbrkn) ;
				
                		/* gains taxed at 1st CG rate */
						CGaXstate = max(0,min(CGa,min(amtiae,ltcg+(Fxtaxtype="cgmax6")*div))) ;
						taxCGaXstate = (Fxr1/100)*CGaXstate;

                		/* gains taxed at 2nd CG rate */
						CGbXstate = max(0,min(amtiae,ltcg+(Fxtaxtype="cgmax6"))-CGaXstate);
						taxCGbXstate = (Fxr2/100)*CGbXstate;

                		/* tax liability with CG adjustment */
                		tamtALTCG = tamtEXCG + taxCGaXstate + taxCGbXstate ;

						tamt = min(tamtnorm,tamtALTCG) ;
        			end;
					else do ;
						tamt=tamtnorm ;
						CGaXstate=0 ;
						CGbXstate=0 ;
						tamtEXCG=0 ;
						tamtALTCG=0 ;
					end ;
				end ;

                /* re-calculate AMT liability */
                amt=max(0, tamt-Fdtxliab_bc_S-FtaxMIN_S);

	            if mintaxtype=4 then do ;
					StaxTAMT = (mintaxrate/100)*tamt;
					StaxMIN=0;
				end;
				else if mintaxtype=6 then do;
					StaxTAMT = min((mintaxrate/100)*tamt, (mintaxex/100)*amtiae);
					StaxMIN = 0;
				end;
			end ;
			/* Iowa AMT */
        	else if mintaxtype=7 then do ; 
				if year<1987 then do ;
					amti = Famti_S ;
                	amtexempt=max(0,mintaxex-(Famtexrate/100)*max(0,amti-Famtexth));
                	StaxTAMT = (mintaxrate/100)*max(0,amti-amtexempt) ;
					if separate=1 then do ;
						amti1=amti*(max(agi1,0)/max(max(agi1,0)+max(agi2,0),1)) ;
						amti2=amti*(max(agi2,0)/max(max(agi1,0)+max(agi2,0),1)) ;
                		StaxTAMT1 = (mintaxrate/100)*max(0,amti1-amtexempt/2) ;
                		StaxTAMT2 = (mintaxrate/100)*max(0,amti2-amtexempt/2) ;
					end;
					StaxMIN=0 ;
				end ;
				else do ;	
				/* if itemizing */
				/* Note: medical expenses fixed July 2007 and March 2008 -- JMB */
					amtiYI =
						agi + otaxpref + oamtadj - itemded - (itemlim=1)*(Famttype>=5)*Fitemlost + (proptax+tax_nonincome_S
						+ min(.025*max(Fagi,0) , max(0,medexp-(Fmedded/100)*max(Fagi,0)))
						+ max(0,busex+miscdedlim-.02*max(Fagi,0))
                    	+((Famttype=4)+(Famttype=5))*charcg) ;
                	amtexemptYI=max(0,mintaxex-(Famtexrate/100)*max(0,amtiYI-Famtexth));
                	StaxTAMTyi = (mintaxrate/100)*max(0,amtiYI-amtexemptYI) ;
					if separate=1 then do ;
						amtiYI1=amtiYI*(max(agi1,0)/max(max(agi1,0)+max(agi2,0),1)) ;
						amtiYI2=amtiYI*(max(agi2,0)/max(max(agi1,0)+max(agi2,0),1)) ;
                    	amtexemptYI1=max(0,(mintaxex/2)-(Famtexrate/100)*max(0,amtiYI1-(Famtexth/2)));
                    	amtexemptYI2=max(0,(mintaxex/2)-(Famtexrate/100)*max(0,amtiYI2-(Famtexth/2)));
	            		StaxTAMTyi1 = (mintaxrate/100)*max(amtiYI1-amtexemptYI1,0) ;	
	            		StaxTAMTyi2 = (mintaxrate/100)*max(amtiYI2-amtexemptYI2,0) ;
					end ;
					/* if not itemizing */
					amtiNI = agi + otaxpref + oamtadj ; 
                	amtexemptNI=max(0,mintaxex-(Famtexrate/100)*max(0,amtiNI-Famtexth));
                	StaxTAMTni = (mintaxrate/100)*max(0,amtiNI-amtexemptNI) ;
					if separate=1 then do ;
						amtiNI1=amtiNI*(max(agi1,0)/max(max(agi1,0)+max(agi2,0),1)) ;
						amtiNI2=amtiNI*(max(agi2,0)/max(max(agi1,0)+max(agi2,0),1)) ;
                    	amtexemptNI1=max(0,(mintaxex/2)-(Famtexrate/100)*max(0,amtiNI1-(Famtexth/2)));
                    	amtexemptNI2=max(0,(mintaxex/2)-(Famtexrate/100)*max(0,amtiNI2-(Famtexth/2)));  
	            		StaxTAMTni1 = (mintaxrate/100)*max(amtiNI1-amtexemptNI1,0) ;	
	            		StaxTAMTni2 = (mintaxrate/100)*max(amtiNI2-amtexemptNI2,0) ;		
					end ;

					/* Determine itemization status for purposes of Iowa alternative minimum tax */
					if iteration=1 then do ;
						if StaxTAMTyi <= StaxTAMTni then SMINitemizer=1 ;
						else SMINitemizer=0 ;
						if separate=1 then do ;
							if (StaxTAMTyi1+StaxTAMTyi2) <= (StaxTAMTni1+StaxTAMTni2) then SMINitemizerSEP=1 ;
							else SMINitemizerSEP=0 ;
						end ;
					end ;
					else do ;
						SMINitemizer = SMINitemizerCONSTANT ;
						SMINitemizerSEP = SMINitemizerSEPCONSTANT ;
					end ;

					/* Determine Iowa tentative alternative minimum tax */
					if SMINitemizer=1 then StaxTAMT = StaxTAMTyi ;
					else StaxTAMT = StaxTAMTni ;
					if separate=1 then do ;
						if SMINitemizerSEP=1 then do ;
							StaxTAMT1 = StaxTAMTyi1 ;
							StaxTAMT2 = StaxTAMTyi2 ;
						end ;
						else do ;
							StaxTAMT1 = StaxTAMTni1 ;
							StaxTAMT2 = StaxTAMTni2 ;
						end ;
					end ;
					/* Set value of StaxMIN to zero for now because of mintaxapp.
					StaxMIN will be recalculated later and applied at the appropriate
					point in the tax calculcation process */
					StaxMIN=0;
				end;
			end;
			/* MINTAXTYPE=8: Rhode Island AMT, 2003-present */	
			else if mintaxtype=8 then do ;
                /* Calculate AMT exemption after any phase-outs, and amtiae */
                amtexempt=max(0, mintaxex-(Famtexrate/100)*max(0,Famti_S-Famtexth));
                amtiae=max(0, Famti_S-amtexempt);
				/* Calculate StaxTAMT */
                    %bracketreader(amtiae, TAMT, Famtrate, Famtbracket, Famtbrkn) ;
					StaxTAMT = (mintaxrate/100)*TAMT ;

					/* For those subject to alternative capital gains computation */
					if (xtaxtype="cgmax5" and ltcg ne 0) then do;
                		amtiaeEXCG=max(0, amtiae-min(amtiae,ltcg));
                		%bracketreader(amtiaeEXCG, TAMTEXCG, Famtrate, Famtbracket, Famtbrkn) ;
						StaxTAMTEXCG = (mintaxrate/100)*TAMTEXCG ;

                		/* gains taxed at 1st CG rate */
						SCGaX = max(0,min(SCGa,min(amtiae,ltcg))) ;
						StaxCGaX = (xr1/100)*SCGaX;

                		/* gains taxed at 2nd CG rate */
						SCGbX = max(0,min(amtiae,ltcg)-SCGaX);
						StaxCGbX = (xr2/100)*SCGbX;

                		/* tax liability with CG adjustment */
                		StamtALTCG = StaxTAMTEXCG + StaxCGaX + StaxCGbX ;

						StaxTAMT = min(StaxTAMT,StamtALTCG) ;
					end ;
				StaxMIN=0 ;
			end ;
			/* MINTAXTYPE=9: Maine AMT, 2003-present */
			/* Same as mintaxtype=8, except remove social security benefits and excluded pensions from AMTI */	
			else if mintaxtype=9 then do ;
                /* Calculate AMT exemption after any phase-outs, and amtiae */
                amtexempt=max(0, mintaxex-(Famtexrate/100)*max(0,Famti_S-Fssagi-retexamt-Famtexth));
                amtiae=max(0, Famti_S-Fssagi-retexamt-amtexempt);
				/* Calculate StaxTAMT */
                    %bracketreader(amtiae, TAMT, Famtrate, Famtbracket, Famtbrkn) ;
					StaxTAMT = (mintaxrate/100)*TAMT ;

					/* For those subject to alternative capital gains computation */
					if (xtaxtype="cgmax5" and ltcg ne 0) then do;
                		amtiaeEXCG=max(0, amtiae-min(amtiae,ltcg));
                		%bracketreader(amtiaeEXCG, TAMTEXCG, Famtrate, Famtbracket, Famtbrkn) ;
						StaxTAMTEXCG = (mintaxrate/100)*TAMTEXCG ;

                		/* gains taxed at 1st CG rate */
						SCGaX = max(0,min(SCGa,min(amtiae,ltcg))) ;
						StaxCGaX = (xr1/100)*SCGaX;

                		/* gains taxed at 2nd CG rate */
						SCGbX = max(0,min(amtiae,ltcg)-SCGaX);
						StaxCGbX = (xr2/100)*SCGbX;

                		/* tax liability with CG adjustment */
                		StamtALTCG = StaxTAMTEXCG + StaxCGaX + StaxCGbX ;

						StaxTAMT = min(StaxTAMT,StamtALTCG) ;
					end ;
				StaxMIN=0 ;
			end ;
			else do ;
				StaxTAMT=0 ;
				StaxMIN=0 ;
			end ;
	   	end;
       	if mintaxapp=1 then do ;
			if StaxMIN>0 then StaxAMIN = StaxASP+StaxMIN;
			else if StaxTAMT>0 then do ;
				StaxMIN = max(0, StaxTAMT - StaxASP);
				StaxAMIN = StaxASP + StaxMIN ;
			end;
			else StaxAMIN=StaxASP;
			if separate=1 then do;
				if mintaxtype = 7 then do ;
					StaxMIN1 = max(0, StaxTAMT1 - StaxASP1) ;
					StaxMIN2 = max(0, StaxTAMT2 - StaxASP2) ;
				end ;
				else do ;
					StaxMIN1 = StaxMIN*min(1,max(0,(StaxASP1/max(StaxASP1+StaxASP2,1)))) ;
					StaxMIN2 = StaxMIN*(1- min(1,max(0,(StaxASP1/max(StaxASP1+StaxASP2,1)))) ) ;
				end ;
				StaxAMIN1=StaxASP1+StaxMIN1 ;
				StaxAMIN2=StaxASP2+StaxMIN2 ;
			end;
		end;
		else do ;
			StaxAMIN=StaxASP;
			if separate=1 then do;
				StaxAMIN1=StaxASP1;
				StaxAMIN2=StaxASP2;
			end;
		end;

        /*********************************************************************
        * State credits other than EITC                                      *
        * Includes general credits, retirement credits,                      *
        * and low-income credits                                             *
        **********************************************************************/

        /*********************************************************************
        * State general credits												 *
		* crednum = number of credits (used in phase-out calculations)       *
        **********************************************************************/
        gencred = crpercap*(1+(filertype="m")+deps) + crreturn
                        + (cred_dep * deps) + (cred_age * agenum) ;

        crednum=0;
        if crpercap>0 then crednum=(1+(filertype="m")+deps);
        if crreturn>0 then crednum=crednum+1;
        if cred_dep>0 then crednum=crednum+deps;
        if cred_age>0 then crednum=crednum+agenum;

			/* married flining separately */
			if separate=1 then do ;
				if credalloc>0 then do ;
        			gencred1 = crpercap*(1+deps1) + (crreturn/2)
                		+ (cred_dep * deps1) + (cred_age * (agex>=65)) ;
        			gencred2 = crpercap*(1+deps2) + (crreturn/2)
                		+ (cred_dep * deps2) + (cred_age * (agespx>=65)) ;
				end ;
				else do ;
					gencred1=gencred*min(1,max(0,(StaxAMIN1/max(StaxAMIN1+StaxAMIN2,1)))) ;
					gencred2=gencred*(1-min(1,max(0,(StaxAMIN1/max(StaxAMIN1+StaxAMIN2,1))))) ;
				end ;
			end ;

        /* Credit phase-outs */
        if crphthresh>0 and agi>=crphthresh then
                gencred=max(0, gencred-(crphrate/100)*crednum*(agi-crphthresh));


        /*********************************************************************
        * State retirement credits                                           *
        * retcred = value of non-refundable retirement credits               *
        * retcredref = value of refundable retirement credits                *
		* note: all of the retirement credits are in states where filing     *
		* jointly is advantageous
        **********************************************************************/
        if retexamt=0 and (retextype ne 1) and
        ((agex>retexage) or (agespx>retexage)) then do;
                /* maximum credit amounts */
                if retextype=8 then do ;
                        if pension<retph2 then retcred=0;
                        else if pension>=retph2 then
                                retcred
                                = agequal*max(0,retex-((retph1-pension)/(retph1-retph2))*retex);
                        retcredref=0;
                end;
                else if retextype=10 then do ;
                        retcredref=retex*agequal ;
                        if retph1>0 and retph1=retph2 and agi>=retph1 then retcredref=0;
                        else if retph1>0 then
                                retcredref=max(0, retcredref-((max(agi,0)-retph1)/max(1,retph2-retph1))*retcredref);
                        retcred=0;
                end;
                else if retextype=12 then do;
                        retcred=retex*agequal ;
                        if retph1>0 and retph1=retph2 and agi>=retph1 then retcred=0;
                        else if retph1>0 then
                                retcred=max(0, retcred-((max(agi,0)-retph1)/max(1,retph2-retph1))*retcred);
                        retcredref=0;
                end;
                else if retextype=15 then do;
                        if agi<retph1 then retcred=agequal*(.09*max(0,retex-ssben)) ;
                        else retcred=agequal*max(0,.09*max(0,retex-ssben)-.09*(agi-retph1));
                        retcredref=0;
                end;
                else do;
                        retcred=0;
                        retcredref=0;
                end;
        end;
        else do;
                retcred=0;
                retcredref=0;
        end;

        /******************************************************
		* State credit that is a percentage of federal credit *
		* for elderly and disabled  						  *
		*******************************************************/
		retcred = retcred + (pctfdeldcr/100)*Feldcred ;

		/***************************************
		* State credits for child care expenses *
		****************************************/
		/* kcrefshare = share of child care credit that is refundable */
		kcrefshare = kidcareref ;

		/* state child care credit calculations */		
		if kidcaretype>10 and kids1>0 then do ;
			if kidcaretype=11 then kcarecred=(kc1/100)*Fkcarecred ;
			else if kidcaretype=12 then do ;
				if kc5=0 then kcarebase=Fkcarecred ;
				else do ;
					if kids1=1 then kcarebase = Fkcarerate*min(childcare,kc5) ;
					else if kids1>1 then kcarebase = Fkcarerate*min(childcare,kc6) ;
					else kcarebase=0 ;
				end ;
				if agi<kc3 then kcarecred=(kc1/100)*kcarebase ;
				else if agi>=kc4 then kcarecred=(kc2/100)*kcarebase ;
				else kcarecred = (kc2/100)*kcarebase + ((kc1-kc2)/100)*kcarebase*(1-((agi-kc3)/(kc4-kc3))) ;
			end ;
			else if kidcaretype=13 then do ;
				if kc2=0 then kcarebase=Fkcarecred ;
				else do ;
					if kids1=1 then kcarebase = min(childcare,kc2) ;
					else if kids1=2 then kcarebase = min(childcare,kc3) ;
					else if kids1>2 then kcarebase = min(childcare,kc4) ;
					else kcarebase=0 ;
				end ;
				kcarecred = (kc1/100)*kcarebase ;
			end ;
			else if kidcaretype=14 then do ;
				if kc5=0 then kcarebase=Fkcareded ;
				else do ;
					if kids1=1 then kcarebase = min(childcare,kc5) ;
					else if kids1>1 then kcarebase = min(childcare,kc6) ;
					else kcarebase=0 ;
				end ;
				if agi<kc3 then kcarecred=(kc1/100)*kcarebase ;
				else if agi>=kc4 then kcarecred=(kc2/100)*kcarebase ;
				else kcarecred = (kc2/100)*kcarebase + ((kc1-kc2)/100)*kcarebase*(1-(agi-kc3)/(kc4-kc3)) ;
			end ;
			else if kidcaretype=15 then do ;
				kcarecred=min(kc2,(kc1/100)*Fkcarecred) ;				
			end ;
			else if kidcaretype=16 then do ;
				if agi<kc3 then kcarecred=(kc1/100)*Fkcarecred ;
				else if agi>=kc4 then kcarecred=max(kc5,(kc2/100)*Fkcarecred) ;
				else kcarecred = (kc2/100)*Fkcarecred + ((kc1-kc2)/100)*Fkcarecred*(1-(agi-kc3)/(kc4-kc3)) ;				
			end ;
			else if kidcaretype=17 then do ;
				if agi<kc3 then kcarecred=(kc1/100)*min(Fkcarecred,Fdtxliab_bc) ;
				else if agi>=kc4 then kcarecred=(kc2/100)*min(Fkcarecred,Fdtxliab_bc) ;
				else kcarecred = (kc2/100)*min(Fkcarecred,Fdtxliab_bc) 
					+ ((kc1-kc2)/100)*min(Fkcarecred,Fdtxliab_bc)*(1-((agi-kc3)/(kc4-kc3))) ;				
			end ;
			else if kidcaretype=18 then do ;
				kcarecred=(kc1/100)*Fkcarecred ;
				kcrefshare = min(Fkcarecred, kc2)/max(1,kcarecred) ;
			end ;
			else if kidcaretype=19 then do ;
				if stateyear=1983 then kcarebase=.2*Fkcareded ;
				else kcarebase = Fkcarecred ;
				if kids1=1 then do ;
					if agi<kc4 then kcarecred = (kc1/100)*kcarebase ;
					else if agi>=kc5 then kcarecred=0 ;
					else kcarecred = (kc1/100)*kcarebase*(1-min(1,(max(0,agi-kc4)/(kc5-kc4)))) ;
				end ;
				else if kids1>1 then do ;
					if agi<kc4 then kcarecred = (kc1/100)*kcarebase ;
					else if agi>=kc6 then kcarecred=0 ;
					else kcarecred = (kc1/100)*kcarebase*(1-min(1,(max(0,agi-kc4)/(kc6-kc4)))) ;
				end ;
				else kcarecred=0 ;
 			end ;
			else if kidcaretype=20 then do ;
				if kc5=0 then kcarebase=Fkcarecred ;
				else do ;
					if kids1=1 then kcarebase = Fkcarerate*min(childcare,kc5) ;
					else if kids1>1 then kcarebase = Fkcarerate*min(childcare,kc6) ;
					else kcarebase=0 ;
				end ;
				if agi<kc3 then kcarecred=(kc1/100)*kcarebase ;
				else if agi>=kc4 then kcarecred=(kc2/100)*kcarebase ;
				else kcarecred = (kc2/100)*kcarebase + ((kc1-kc2)/100)*kcarebase*(1-((agi-kc3)/(kc4-kc3))) ;
				if agi>=kc4 then kcrefshare=0 ;
					else kcrefshare=1 ;
			end ;
			else if kidcaretype=21 then do ;
				if agi<kc5 then do ;
					if kids1=1 then kcarecred
						= max(0,((kc1/100)*min(childcare,kc2))-min(Fdtxliab_bc,Fkcarecred)) ;
					else if kids1=2 then kcarecred
						= max(0,((kc1/100)*min(childcare,kc3))-min(Fdtxliab_bc,Fkcarecred)) ;
					else if kids1>2 then kcarecred
						= max(0,((kc1/100)*min(childcare,kc4))-min(Fdtxliab_bc,Fkcarecred)) ;
				end ;
				else kcarecred=0 ;
			end ;
			else if kidcaretype=22 then kcarecred = 
				((kc1 + kc2*min(kc3, max(0, kc4-max(0,agi)))/kc5)/100)*Fkcarecred ;
			else if kidcaretype=23 then do ;
				if agi<kc6 then kcarecred = 
					((kc1 + kc2*min(kc3, max(0, kc4-max(0,agi)))/kc5)/100)*Fkcarecred ;
				else kcarecred = 
					((xb1 + xb2*min(xb3, max(0, xb4-max(0,agi)))/xb5)/100)*Fkcarecred ;
			end ;
			else if kidcaretype=24 then do ;
				if agi<kc2 then kcarecred = (kc1/100)*Fkcarecred ;
				else if agi<kc4 then kcarecred = (kc3/100)*Fkcarecred ;
				else kcarecred=0 ;
			end ;
			else if kidcaretype=25 then do ;
				if kids1=0 then kcarecred=0 ;
				else if kids1=1 then kcarecred = min(childcare,kc2) ;
				else if kids1=2 then kcarecred = min(childcare,kc3) ;
				else if kids1>2 then kcarecred = min(childcare,kc4) ;
				if agi>kc5 then kcarecred = max(0,kcarecred - (kc6/100)*max(agi-kc5,0)) ;
			end ;
			else if kidcaretype=26 then do ;
				if agi<kc3 then kcarebase=(kc1/100)*Fkcareded ;
				else if agi>=kc4 then kcarebase=(kc2/100)*Fkcareded ;
				else kcarebase = (kc2/100)*Fkcareded + ((kc1-kc2)/100)*Fkcareded*max(0,(1-((agi-kc3)/(kc4-kc3)))) ;
				if labinc>=xb4 then do ;
					if agi<(xb2 + xb3*((filertype="m")+deps)) then
						kcarecred=(xb1/100)*Fkcarecred ;
					else if agi>=1.25*(xb2 + xb3*((filertype="m")+deps)) then kcarecred=0 ;
					else kcarecred = (xb1/100)*Fkcarecred*
						(1-((agi-(xb2+xb3*((filertype="m")+deps)))/((xb2+xb3*((filertype="m")+deps))*.25))) ;
				end ;				
				else kcarecred=0 ;
				kcrefshare = kcarecred/max(1,kcarebase+kcarecred);
				kcarecred = kcarebase+kcarecred; 
			end ;
			else if kidcaretype=27 then do ;
				if agi<kc3 then do ;
					kcarecred=(kc1/100)*Fkcarecred ;
					kcrefshare=1 ;
				end ;
				else do ;
					kcarecred=(kc2/100)*Fkcarecred ;
					kcrefshare=0 ;
				end ;
			end ;
		end ; 
		else kcarecred=0 ;

		if separate=1 then do ;
			if kidcaretype=11 and kc2=1 then do ;
				if labinc2<labinc1 then do ;
					kcarecred1=0 ;
					kcarecred2=kcarecred ;
				end ;
				else do ;
					kcarecred1=kcarecred ;
					kcarecred2=0 ;
				end ;
			end ;
			else if kidcaretype=11 and kc2=2 then do ;
				kcarecred1=kcarecred*(max(agi1,0)/max(max(agi1,0)+max(agi2,0),1)) ;
				kcarecred2=kcarecred*(max(agi2,0)/max(max(agi1,0)+max(agi2,0),1)) ;				
			end ;
			else do ;
				kcarecred1=kcarecred*min(1,max(0,(StaxAMIN1/max(StaxAMIN1+StaxAMIN2,1)))) ;
				kcarecred2=kcarecred*(1-min(1,max(0,(StaxAMIN1/max(StaxAMIN1+StaxAMIN2,1))))) ;
			end ;
		end ;


        /*********************************************************
        * State low-income credits                               *
        * lowcred = non-refundable low-income credit             *
        * lowcredref = refundable low-income credit              *
        **********************************************************/
        if (lowtype ne 6 and lowtype ne 13 and lowtype ne 14 and lowtype ne 15
        	and lowtype ne 17) and(agi<(lowph2+(lowphdep*deps)))
        	then do;
                if filertype="m" then agequal=((agex>=lowminage)+(agespx>=lowminage))/2 ;
                else if filertype="s" or filertype="h" then agequal=(agex>lowminage) ;
                /* Non-refundable credit */
                if lowtype=2 then do;
                        if lowph1=0 then lowcred=(low+lowdepamt*deps)*max(0,1-(max(agi,0)/max(lowph2+lowphdep*deps,1)));
                        else if agi<(lowph1+lowphdep*deps) then lowcred=low;
                        else if lowph1=lowph2 then lowcred=0;
                        else lowcred=(low+lowdepamt*deps)*max(0,(1-((max(agi,0)-(lowph1+lowphdep*deps))/(lowph2-lowph1))));
                        lowcredref=0;
						if separate=1 then do ;
							lowcred1=min(1,max(0,(StaxAMIN1/max(StaxAMIN1+StaxAMIN2,1))))*lowcred ;
							lowcred2=(1-min(1,max(0,(StaxAMIN1/max(StaxAMIN1+StaxAMIN2,1)))))*lowcred ;
						end ;
                end;
                /* Refundable credit */
                else if lowtype=3 then do;
                        if lowph1=0 then lowcredref=(low+(lowdepamt*deps)+(loweldamt*agenum))
                                *(1-(max(agi,0)/(lowph2+lowphdep*deps)));
                        else if agi<(lowph1+lowphdep*deps)
                                then lowcredref=low+(lowdepamt*deps)+(loweldamt*agenum);
                        else if lowph1=lowph2 then lowcredref=0;
                        else lowcredref=(low+(lowdepamt*deps)+(loweldamt*agenum))
                                *max(0,1-((max(agi,0)-(lowph1+lowphdep*deps))/(lowph2-lowph1)));
                        lowcredref=lowcredref*agequal;
                        lowcred=0;
                end;
                /* Per capita non-refundable credit */
                else if lowtype=4 then do;
                        if lowph1=0 then lowcred=low*(1+(filertype="m")+deps)
                                *max(0,1-(max(agi,0)/max(1,lowph2+lowphdep*deps)));
                        else if agi<(lowph1+lowphdep*deps)
                                then lowcred=low*(1+(filertype="m")+deps);
                        else if lowph1=lowph2 then lowcred=0;
                        else lowcred=low*(1+(filertype="m")+deps)
                                *max(0,1-((max(agi,0)-(lowph1+lowphdep*deps))/(lowph2-lowph1)));
                        lowcredref=0;
						if separate=1 then do ;
							lowcred1=min(1,max(0,(StaxAMIN1/max(StaxAMIN1+StaxAMIN2,1))))*lowcred ;
							lowcred2=(1-min(1,max(0,(StaxAMIN1/max(StaxAMIN1+StaxAMIN2,1)))))*lowcred ;
						end ;
                end;
                /* Per capita non-refundable credit plus age credit */
                else if lowtype=7 then do;
                        if lowph1=0 then lowcred=low*(1+(filertype="m")+deps+agenum)
                                *max(0,1-(max(agi,0)/max(1,lowph2+lowphdep*deps)));
                        else if agi<(lowph1+lowphdep*deps)
                                then lowcred=low*(1+(filertype="m")+deps+agenum);
                        else if lowph1=lowph2 then lowcred=0;
                        else lowcred=low*(1+(filertype="m")+deps+agenum)
                                *max(0,1-((max(agi,0)-(lowph1+lowphdep*deps))/(lowph2-lowph1)));
                        lowcredref=0;
                end;
                /* Refundable per capita credit (HI, KS) */
                else if lowtype=8 and agex>lowminage then do;
                        if lowph1=0 then lowcredref=(low*(1+(filertype="m")+deps)+loweldamt*agenum)
                                *max(0,1-(max(agi,0)/max(1,lowph2+lowphdep*deps)));
                        else if agi<(lowph1+lowphdep*deps)
                                then lowcredref=low*(1+(filertype="m")+deps) + loweldamt*agenum;
                        else if lowph1=lowph2 then lowcredref=0;
                        else lowcredref=(low*(1+(filertype="m")+deps)+loweldamt*agenum)
                                *max(0,1-((max(agi,0)-(lowph1+lowphdep*deps))/(lowph2-lowph1)));
                        lowcred=0;
                end;
				/* Refundable per capita credit, Kansas ("food sales tax refund") 1986-97 */
                else if lowtype=21 then do;
						if kids2>0 or agex>=lowminage then do ;
                          	if income<lowph1 then lowcredref=low+lowdepamt*((filertype="m")+deps) ;
                        	else if income<lowph2 then lowcredref=low+lowdepamt*((filertype="m")+deps)*
								(1-(max(income-lowph1,0)/(lowph2-lowph1))) ;
                        	else lowcredref=0 ;
						end ;
						else lowcredref=0 ;
                        lowcred=0;
                end; 
				/* Refundable per capita credit, Kansas ("food sales tax refund") 1998-99 */
                else if lowtype=22 then do;
						if kids2>0 or agex>=lowminage then do ;
                          	if income<lowph1 then lowcredref=low*(1+(filertype="m")+deps) ;
                        	else if income<lowph2 then lowcredref=(low/2)*(1+(filertype="m")+deps) ;
                        	else lowcredref=0 ;
						end ;
						else lowcredref=0 ;
                        lowcred=0;
                end;
				/* Refundable per capita credit, Kansas ("food sales tax refund") 2000-present */
                else if lowtype=23 then do;
						if kids2>0 or agex>=lowminage then do ;
                          	if income<lowph1 then lowcredref=low*(1+(filertype="m")+(filertype="h")+deps) ;
                        	else if income<lowph2 then lowcredref=(low/2)*(1+(filertype="m")+(filertype="h")+deps) ;
                        	else lowcredref=0 ;
						end ;
						else lowcredref=0 ;
                        lowcred=0;
                end;
				/* Non-refundable credit for OASDI taxes ("working taxpayer tax credit"), Arkansas 1998-2002 */
				else if lowtype=18 then do ;
					if income<lowph1 then lowcred=(low/100)*(Fssrate/200)*
						max(0,min(min(wagsal1+seinc1,Fsscap)+min(wagsal2+seinc2,Fsscap),income)) ;
					else lowcred=(lowdepamt/100)*(Fssrate/200)*
						max(0,min(min(wagsal1+seinc1,Fsscap)+min(wagsal2+seinc2,Fsscap),income,lowph2)) ;
					lowcredref=0 ;
				end ;
                /* Special "earned income credit" (Indiana) */
                else if lowtype=9 then do;
                        if labinc>=(.8*(max(Fagi+othadj,0))) or kids2=0 then lowcred=0;
                        else lowcred=(low/100)*max(0,lowph2-(max(Fagi,0)+othadj));
                        lowcredref=0;
                end;
                /* Another special earned income credit */
                else if lowtype=11 then do;
                        if agi>=(lowph1 + lowphdep*deps) then lowcred=0;
                        else lowcred=(low/100)*labinc;
                        lowcredref=0;
                end;
                /* % of tax liability credit */
                else if lowtype=12 and agi<lowph2 then do;
                        if lowph1=0
                                then lowcred=(low/100)*StaxASP*max(0,1-(max(agi,0)/(lowph2+lowphdep*deps)));
                        else if agi<(lowph1+lowphdep*deps) then lowcred=(low/100)*StaxASP;
                        else if lowph1=lowph2 then lowcred=0;
                        else lowcred=(low/100)*StaxASP
                                *max(0,1-((max(agi,0)-(lowph1+lowphdep*deps))/(lowph2-lowph1)));
                        lowcredref=0;
						if statename="ca" and StaxMIN>0 then lowcred=0 ;
                end;
                /* Child credit (NC) */
                else if lowtype=16 then do;
                        if agi<lowph1 then lowcred=kids3*lowdepamt;
                        else lowcred=0;
                        lowcredref=0;
                end;
                else do;
                        lowcred=0 ;
                        lowcredref=0;
                end;
        end;
        /* No-tax floors */
        else if (lowtype=13 or lowtype=14 or lowtype=15 or lowtype=6 or lowtype=20) then do;
                /* No-tax floor equal to federal filing threshold */
                if lowtype=13 or lowtype=15 then do;
						if statename ne "dc" then do ;
                        	if agi<(Fstded+Fexempt) then lowcred=StaxAMIN;
                        	else lowcred=0;
                        	lowcredref=0;
							if separate=1 and agi<(Fstded+Fexempt) then do ;
								lowcred1=StaxAMIN1 ;
								lowcred2=StaxAMIN2 ;
							end ;
							else do ;
								lowcred1=0 ;
								lowcred2=0 ;
							end ;
						end ;
						else if statename = "dc" then do ;
                        	if agi<(Fstded+Fexempt) then lowcred=max(StaxAMIN-kcarecred-(eicstate1/100)*Feic,0) ;
                        	else lowcred=0;
                        	lowcredref=0;
							if separate=1 and agi<(Fstded+Fexempt) then do ;
								lowcred1=min(1,max(0,(StaxAMIN1/max(StaxAMIN1+StaxAMIN2,1))))*
									max(StaxAMIN1+StaxAMIN2-kcarecred-(eicstate1/100)*Feic,0) ;
								lowcred2=(1-min(1,max(0,(StaxAMIN1/max(StaxAMIN1+StaxAMIN2,1))))) *
									max(StaxAMIN1+StaxAMIN2-kcarecred-(eicstate1/100)*Feic,0) ;
							end ;
							else do ;
								lowcred1=0 ;
								lowcred2=0 ;
							end ;
						end ;
                end;
                /* Same, but tax cannot reduce after-tax income below threshold */
                else if lowtype=14 then do;
                        if agi<(Fstded+Fexempt) then lowcred=StaxAMIN;
                        else lowcred=max(0,Fstded+Fexempt-agi-StaxAMIN);
                        lowcredref=0;
						if separate=1 and agi<(Fstded+Fexempt) then do ;
							lowcred1=min(1,max(0,(StaxAMIN1/max(StaxAMIN1+StaxAMIN2,1))))*
								max(0,Fstded+Fexempt-agi-StaxAMIN1-StaxAMIN2);
							lowcred2=(1- min(1,max(0,(StaxAMIN1/max(StaxAMIN1+StaxAMIN2,1)))) )*
								max(0,Fstded+Fexempt-agi-StaxAMIN1-StaxAMIN2);
						end ;
						else do ;
							lowcred1=0 ;
							lowcred2=0 ;
						end ;
                end;
                /* If AGI>no-tax-floor, pay lesser of x% of (AGI-threshold) or regular tax */
                else if lowtype=6 then do;
                        if agi<(lowph1+lowphdep*deps) then lowcred=StaxAMIN;
                        else if agi>=(lowph2*(lowph1+lowphdep*deps)) then lowcred=0;
                        else lowcred=max(0,StaxAMIN-(low/100)*max(0,agi-(lowph1+lowphdep*deps)));
                        lowcredref=0;
                end;
				else if lowtype=20 then do ;
					if (Fdtxliab_bc_S + Famt_S) = 0 then lowcred=max(0,StaxAMIN-gencred-kcarecred) ;
					lowcredref=0 ;
				end ;
                else do;
                        lowcred=0;
                        lowcredref=0;
                end;
        end;
        /* Credit that is an increasing function of income */
        else if lowtype=17 then do;
                if agi<lowph1 then lowcredref=low;
                else if agi>=lowph2 and (filertype="s" or filertype="h")
                        then lowcredref=lowdepamt;
                else if agi>=lowph2 and filertype="m"
                        then lowcredref=loweldamt;
                else if (filertype="s" or filertype="h")
                        then lowcredref=low+(lowdepamt-low)*((agi-lowph1)/(lowph2-lowph1));
                else if filertype="m"
                        then lowcredref=low+(loweldamt-low)*((agi-lowph1)/(lowph2-lowph1));
                lowcred=0;
        end;
        else do;
                lowcred=0;
                lowcredref=0;
        end;
		if separate=1 then do ;
			if lowcred1=. then lowcred1=0 ;
			if lowcred2=. then lowcred2=0 ;
		end ;

		/*********************************************************
		Child credit that is a percentage of federal child credit
		New York starting in 2006
		**********************************************************/
		if sptx="kidcred" then do ;
   			lowcredref = (sptxrate/100)*(Fkidcred_S + Fkidcredref_S) ;
			if Fagi < Fkidcthresh then lowcredref = max(sptxex*kids3,lowcredref) ;
		end ;

        /****************************************
        * Miscellaneous state credits           *
        * (Added on to lowcredref)              *
        *****************************************/
        if (miscextype=7 or miscextype=8 or miscextype=10) then do;
                if miscextype=7 then lowcredref=lowcredref+
                        (1+(filertype="m")+deps)*miscexamt;
                else if miscextype=8 and agi<30000 then do;
                        if stateyear<1999 and agi<12000 then lowcredref=
                                lowcredref+miscexamt*(1+(filertype="m")+deps);
                        else if stateyear>=1999 then do;
                                if (agenum>0 or deps>0) and agi<30000 then lowcredref=
                                        lowcredref+miscexamt*(1+(filertype="m")+deps);
                                else if agi<15000 then lowcredref=
                                        lowcredref+miscexamt*(1+(filertype="m"));
                        end;
                end;
                else if miscextype=10 and Fagi<5000 then do;
                        lowcredref=lowcredref+miscexamt*deps+(miscexamt/2)*(1+(filertype="m"));
                end;
        end;
		/* Basic no tax floor, coded into miscextype (CA) */
        if miscextype=13 then do ;
        	if agi<miscexamt then StaxAMIN=StaxMIN;
			if separate=1 and agi<miscexamt then do ;
				StaxAMIN1=StaxMIN1 ;
				StaxAMIN2=StaxMIN2 ;
			end ;
		end ;
		/* New Jersey property tax credit */
		if cbtype=17 and (income>xcbthresh5 or agenum>0) and (StaxNORMni-StaxNORMyi<cbincval2) then
			lowcredref = lowcredref + cbincval2 ;

        /***************************************
        * Credits for two-earner couple        *
        ****************************************/
		/* WI, SC */
        if mardedtype=3 and filertype="m" then
            marcred=min(mardedlim,(mardedpct/100)*min(labinc1,labinc2));
		/* MN 1999-2001 */
		else if mardedtype=6 and filertype="m" then do ; 
			if (min(nflabinc1,nflabinc2)<xb1) or (Sti<xb2) then marcred=0 ;
			else if Sti<xb3 then marcred = 
				xb5 + (xb6-xb5)*min(1,max(0,min(nflabinc1,nflabinc2)-xb1)/(xb4-xb1)) ;
			else marcred = xb9 + (xb10-xb9)*min(1,max(0,min(nflabinc1,nflabinc2)-xb7)/(xb8-xb7)) ;
		end ;
		/* OH, 1973-present */
		else if mardedtype=7 and filertype="m" then do ;
			%bracketreader(Sti, junk, xrate, xbracket, xbracknum) ;
           	marcred = (brackmtr/100)*max(0,StaxAMIN-gencred) ;
 			if xagicrmax>0 then marcred=min(marcred,xagicrmax) ;
			if min(agi1-int1-div1-ltcg1-othcg1-rentinc1-othinc1,
				agi2-int2-div2-ltcg2-othcg2-rentinc2-othinc2) < mardedlim
				then marcred=0 ;
		end ;

        /******************************************************************
        * State income tax after credits other than EITC (StaxAGC)        *
        *******************************************************************/
        StaxAGC = max(0, StaxAMIN-gencred-itemcred-retcred-lowcred-marcred-kcarecred*(1-kcrefshare))
                        -retcredref-lowcredref-kcarecred*kcrefshare;
			if separate=1 then do ;
				StaxAGC1 = max(0, StaxAMIN1-gencred1-lowcred1-kcarecred1*(1-kcrefshare))
					-retcredref-lowcredref-kcarecred1*kcrefshare ;
				StaxAGC2 = max(0, StaxAMIN2-gencred2-lowcred2-kcarecred2*(1-kcrefshare))
					-kcarecred2*kcrefshare ;
			end ;

        /********************************************************************
        * State extra taxes                                                 *
        *********************************************************************/
		/* Extra state taxes where separate filing matters:
		with itemized deductions: CO (1947 paratax gi), NY (1933-37 paratax gi), WI (1961 paracred gi)
		other: DE (1943-44 paratax gi), KY (1956-1960 liabtax), NY (1938-1960 paratax cg), 
			ND (1919-22 paratax dcgi), NJ (1976 paratax dcgi), OR (1933-38 paratax di),
			SC (1934-40 paratax di), SD (1935 paratax gi)  
		*/

        /*** Calculate base of extra tax ***/
		if (xtaxtype = "agicred") or (xtaxtype = "dagi") or (xtaxtype = "diagi")
			or (xtaxtype = "liabcred") or (xtaxtype = "liabtax") or (xtaxtype = "maxtax")
			or (xtaxtype = "paracred") or (xtaxtype = "paratax") then do ;

                /* Compute AGI for an extra state tax where the base starts with gross income */
                if (xtaxtype="paratax" or xtaxtype="paracred" or xtaxtype="maxtax")
                and xbase="gi" then do;
                        /* Excluded capital gains (xexltcg) */
                        if ltcg<0 then xexltcg=0;
                        else xexltcg=(xcgexpct/100)*ltcg ;

                        /* Compute AGI (except for social security) for extra tax */
                        xagi=wagsal+businc+farminc
						+(ltcg-xexltcg)+othcg+pension+rentinc+partscorp+othinc
                        +max(0,(1-(xdivexpct/100))*div - xdivexamt)
                        +max(0, (1-(xintexpct/100))*int)
                        +xosa1st*(
					     (conform>1)*(Fuiagi-othadj)
                        -(filertype="m")*(mardedtype=1)*(xosa1st=1)*((Fmarded=1)*0.05+(Fmarded=2)*0.1)*max(min(labinc1,labinc2,30000),0)
                        -(1-Fmovexded)*movex
                        -(1-Fbusexded)*busex
						-(stateyear>1989)*(1/2)*(FsstxliabSE1+FsstxliabSE2)) ;

                        /* Social security benefits in extra tax */
                        if ssagi=. then ssagi=0;
                        if xosa1st=1 then xssagi=ssagi;
                        else xssagi=0;
                        xagi=xagi+xssagi;

						/* separate filers */
						if separate=1 then do ;

	                        xagi1=wagsal1+businc1+farminc1
							+(1-(xcgexpct/100))*ltcg1+othcg1+pension1+rentinc1+partscorp1+othinc1
   	                     	+max(0,(1-(xdivexpct/100))*div1 - xdivexamt/2)
                        	+max(0, (1-(xintexpct/100))*int1)
                        	+xosa1st*(
							 (conform>1)*(Fuiagi*(ui1/max(ui,1))-othadj1)
							+xssagi*(ssben1/max(ssben1+ssben2,1))
                        	-(1-Fmovexded)*movex1
                        	-(1-Fbusexded)*busex1
							-(stateyear>1989)*(1/2)*FsstxliabSE1) ;

	                        xagi2=wagsal2+businc2+farminc2
							+(1-(xcgexpct/100))*ltcg2+othcg2+pension2+rentinc2+partscorp2+othinc2
   	                     	+max(0,(1-(xdivexpct/100))*div2 - xdivexamt/2)
                        	+max(0,(1-(xintexpct/100))*int2)
                        	+xosa1st*(
							 (conform>1)*(Fuiagi*(ui2/max(ui,1))-othadj2)
							+xssagi*(ssben2/max(ssben1+ssben2,1)) 
							-othadj2
                        	-(1-Fmovexded)*movex2
                        	-(1-Fbusexded)*busex2
							-(stateyear>1989)*(1/2)*FsstxliabSE2) ;

							xagi1=xagi1*(1-(xpctex/100)) ;
							xagi2=xagi2*(1-(xpctex/100)) ;
						end ;
                end;

                /* Compute tax base for an extra tax that only taxes components of capital income */
                else if xbase="cg" then do;
                        xagi=max(0, (1-(xcgexpct/100))*ltcg + othcg);
						if separate=1 then do ;
							xagi1=max(0, (1-(xcgexpct/100))*ltcg1 + othcg1)*(1-(xpctex/100));
							xagi2=max(0, (1-(xcgexpct/100))*ltcg2 + othcg2)*(1-(xpctex/100));
						end ;
                end;
                else if xbase="div" then do ;
					xagi=max(0,(1-(xdivexpct/100))*div - xdivexamt);
					if separate=1 then do ;
						xagi1=max(0,(1-(xdivexpct/100))*div1 - xdivexamt/2)*(1-(xpctex/100));
						xagi2=max(0,(1-(xdivexpct/100))*div2 - xdivexamt/2)*(1-(xpctex/100));
					end ;
				end ;
                else if xbase="di" then do ;
					xagi=max(0,(1-(xdivexpct/100))*div - xdivexamt)
                        + max(0,(1-(xintexpct/100))*int);
					if separate=1 then do ;
						xagi1=max(0,(1-(xdivexpct/100))*div1 - xdivexamt/2)
                        	+ max(0,(1-(xintexpct/100))*int1);
						xagi2=max(0,(1-(xdivexpct/100))*div2 - xdivexamt/2)
                        	+ max(0,(1-(xintexpct/100))*int2);
						xagi1=xagi1*(1-(xpctex/100)) ;
						xagi2=xagi2*(1-(xpctex/100)) ;					
					end ;
				end ;
                else if xbase="dcg" then do ;
                	xagi=max(0,(1-(xcgexpct/100))*ltcg+othcg)
						+max(0,(1-(xdivexpct/100))*div-xdivexamt) ;
					if separate=1 then do ;
                		xagi1=max(0,(1-(xcgexpct/100))*ltcg1+othcg1)
							+max(0,(1-(xdivexpct/100))*div1-xdivexamt) ;
                		xagi2=max(0,(1-(xcgexpct/100))*ltcg2+othcg2)
							+max(0,(1-(xdivexpct/100))*div2-xdivexamt) ;
						xagi1=xagi1*(1-(xpctex/100)) ;
						xagi2=xagi2*(1-(xpctex/100)) ;
					end ;
                end;
                else if xbase="dcgi" then do;
                	xagi=max(0,(1-(xcgexpct/100))*ltcg+othcg)
                    	+max(0,(1-(xdivexpct/100))*div-xdivexamt)
                        +max(0,(1-(xintexpct/100))*int) ;
					if separate=1 then do ;
                		xagi1=max(0,(1-(xcgexpct/100))*ltcg1+othcg1)
                    		+max(0,(1-(xdivexpct/100))*div1-xdivexamt)
                        	+max(0,(1-(xintexpct/100))*int1) ;
                		xagi2=max(0,(1-(xcgexpct/100))*ltcg2+othcg2)
                    		+max(0,(1-(xdivexpct/100))*div2-xdivexamt)
                        	+max(0,(1-(xintexpct/100))*int2) ;
						xagi1=xagi1*(1-(xpctex/100)) ;
						xagi2=xagi2*(1-(xpctex/100)) ;
					end ;
                end;

                /**************************************************************
                * Compute state taxable income for each itemization status    *
				* extra state tax that starts with federal taxable income     *
                ***************************************************************/
                else if xbase="fti" then do;

						xagi=Fagi ;
						xstiNI=max(FtiNI-asdfed*xdedfed*max(taxf_S,0),0);
						/* if state income tax is not deductible */
						if sitded=0 then do ;
							if Fitemlost>0 then xitemded = max(0, Fitemded - Fitemlost
								-((iunprotected-Fitemlost)/max(iunprotected,1))*(taxs_S + (Fsaleded=2)*max(salestax-taxs_S,0) ));
							else xitemded = max(0, Fitemded - (taxs_S + (Fsaleded=2)*max(salestax-taxs_S,0) ) ) ;
							xstiYI=max(FtiYI + max(0, Fitemded - xitemded)-xdedfed*max(taxf_S,0), 0) ;
						end ;
						/* if state income tax is deductible */
						else do ;
							xitemded=Fitemded - Fitemlost ;
							xstiYI=max(FtiYI-xdedfed*max(taxf_S,0), 0) ;
						end ;
                end;

                /**************************************************************** 
				* Extra tax or credit that is a function of state tax liability *
				*****************************************************************/
                else if xtaxtype="liabtax" or xtaxtype="liabcred" then do ;
                        xagi=max(StaxAGC,0) ;
						if separate=1 then do ;
							xagi1=max(StaxAGC1,0) ;
							xagi2=max(StaxAGC2,0) ;
						end ;
				end;

				/**********************************************************
                *  Extra taxes or credits where rate is a function of AGI *
				***********************************************************/
                else if xtaxtype="dagi" or xtaxtype="diagi" or xtaxtype="agicred" then do ;
					xagi=Fagi;
					if separate=1 then do ;
						xagi1=agi1 ;
						xagi2=agi2 ;
					end ;
				end ;

                /****************************************** 
				* Percentage exemption in extra state tax *
				*******************************************/
                xagi=xagi*(1-(xpctex/100));

                /***************************************************
                * Personal exemptions in extra state tax (xexempt) *
                ****************************************************/
                xexempt=xexpercap*(1 + (Filertype="m") + deps)
                        + xexreturn + (xex_dep * deps) + (xex_age * agenum) ;

						if separate=1 then do ;
							
							/* non-discretionary exemptions for separate filers */

							if exalloc=1 then do ;
								xexemptND1 = xexpercap + (agex>=65)*xex_age ;
								xexemptND2 = xexpercap + (agespx>=65)*xex_age ;				
							end ;
							else if exalloc=2 then do ;
								xexemptND1 = xexreturn/2 + xexpercap + deps1*(xexpercap + xex_dep) 
									+ (agex>=65)*xex_age ;
								xexemptND2 = xexreturn/2 + xexpercap + deps2*(xexpercap + xex_dep) 
									+ (agespx>=65)*xex_age ;				
							end ;
							else if exalloc=3 then do ;
								xexemptND1 = xexempt*max(agi1,0)/max(max(agi1,0)+max(agi2,0),1) ; 
								xexemptND2 = xexempt*max(agi2,0)/max(max(agi1,0)+max(agi2,0),1) ;  
							end ;
							else if exalloc=4 then do ;
								xexemptND1 = 0 ; xexemptND2 = 0 ;
							end ;
							else do ;
								xexemptND1 = xexpercap + deps1*(xexpercap + xex_dep) + (agex>=65)*xex_age ;
								xexemptND2 = xexpercap + deps2*(xexpercap + xex_dep) + (agespx>=65)*xex_age ;
							end ;

							/* Discretionary exemptions for separate filers */
							xexemptDISC = max(xexempt - xexemptND1 - xexemptND2 , 0) ;
						end ;						

                /********************************************************
                * Itemized deductions in extra state tax where base 	*
				* starts with gross income (xitemded)    				*
                *********************************************************/
                if xbase="gi" then do ;
                        xitemded=
                          xcharded*min(charity,max(0,(chlim/100)*agi))
                        + xintded*(intpaid+invint)
                        + xsitded*taxs_S
                        + (itemiz>0)*(xosa1st=1)*
						(propded*proptax
                        + saleded*salestax
						+ propded*tax_nonincome_S
                        + (medded=1)*max(0,medexp-(Fmedded/100)*max(Fagi,0))
                        + max(0,casualty-(Fcasdedlim/100)*max(Fagi,0)-100)
                        + Fmovexded*movex
                        + Fbusexded*max(0,busex+miscdedlim-.02*max(Fagi,0))
                        + (1-Fbusexded)*miscdedlim
                        + omiscded + Fkcareded) ;

						/* Note: states where separate filing may be advantageous and that
						   have an "extra" tax all have the same itemized deductions as in the regular tax */
						if separate=1 then do ;
							if xintded=1 then do ;
								xitemded1=itemded1 ;
								xitemded2=itemded2 ;
							end ;
							else do ;
								xitemded1=0 ;
								xitemded2=0 ;
							end ;
						end ;
				end ;
                else if xbase ne "fti" then do ;
					xitemded=0;
					if separate=1 then do ;
						xitemded1=0;
						xitemded2=0;
					end ;
				end ;

                /**************************************************
                * Standard deduction in extra state tax (xstded)  *
                ***************************************************/
                if xpctstded=0 then xstded = xmaxstded;
                else xstded=min(xmaxstded,max((xpctstded/100)*xagi,xminstded));
				
				if separate=1 then do ;
						if stdalloc=1 then do ;
							xstded1=min(xmaxstded,max((xpctstded/100)*xagi1,xminstded));
							xstded2=min(xmaxstded,max((xpctstded/100)*xagi2,xminstded));
						end ;
						else do ;
							xstded1=min(xmaxstded/2,max((xpctstded/100)*xagi1,xminstded/2));
							xstded2=min(xmaxstded/2,max((xpctstded/100)*xagi2,xminstded/2));							
						end ;
				end ;

                /******************************************************************
                *    Limitation on itemized deductions in extra state tax	      *
                *    where base starts with gross income                          *
                *******************************************************************/
                if xbase="gi" and xitemlim=1 then xitemded = max(0, xitemded - Fitemlost +
            			Fitemlost*(xsitded=0)*(taxs_S + (Fsaleded=2)*max(salestax-taxs_S,0) )/ max(iunprotected,1));
			

                /********************************************************
                * Determine taxable income in extra state tax (xsti),   *
				* for xbase starting with gi or fti                     *
				* if xtaxtype = paratax, paracred, or maxtax			*
                *********************************************************/
				/* single, HoH, or joint */
				if xbase="gi" or xbase="fti" then do ;
					/* Note: if xbase="fti" then xstiNI and xstiYI were computed above in AGI section */
					if xbase="gi" then do ;
						xstiNI = max(0,xagi-xexempt-xstded-xosa1st*retexamt-asdfed*xdedfed*max(taxf_S,0));
						xstiYI = max(0,xagi-xexempt-max(xitemded,xstded)-xosa1st*retexamt-xdedfed*max(taxf_S,0));
					end ;
					/* Determine itemization status */
					if iteration=1 then do ;
						if itemiz<2 then do ;
							if xstiNI <= xstiYI then do ;
								xsti=xstiNI ;
								xitemizer_s = 0 ;
							end ;
							else do ;
								xsti=xstiYI ;
								xitemizer_s=1 ;
							end ;
						end ;
						else if itemiz=2 or itemiz=4 then do ;
							if Fitemizer_S=0 then do ;
								xsti=xstiNI ;
								xitemizer_s=0 ;
							end ;
							else do ;
								xsti=xstiYI ;
								xitemizer_s=1 ;
							end ;
						end ;
						else if itemiz=3 then do ;
							if Fitemizer_S=0 or xstiNI <= xstiYI then do ;
								xsti=xstiNI ;
								xitemizer_s=0 ;
							end ;
							else do ;
								xsti=xstiYI ;
								xitemizer_s=1 ;
							end ;
						end ;
						else if itemiz=5 then do ;
							if Fitemizer_S=1 or xstiNI > xstiYI then do ;
								xsti=xstiYI ;
								xitemizer_s=1 ;
							end ;
							else do ;
								xsti=xstiNI ;
								xitemizer_s=0 ;
							end ;
						end ;
					end ;
					else do ;
						xitemizer_s = xitemizer_sCONSTANT ;
						if xitemizer_s=0 then xsti=xstiNI ;
						else xsti=xstiYI ;
					end ;

					/* Married filing separately */
					/* Note: there are no examples of an extra tax that meets all three of the following conditions:
					(1) itemiz>1, (2) separate filing may be advantageous, (3) itemized deductions are allowed in the 
					extra tax.  The states that have an extra state tax that allows itemized deductions and where 
					separate filing may be advantageous have the same itemized deductions and standard deduction in 
					both the normal and extra taxes, so we can assume the itemization status is the same */
					if separate=1 and xbase="gi" then do;
							xstiND1 = max(0, xagi1 - itemizerSEP*xitemded1 - (1-itemizerSEP)*xstded1 - xexemptND1
								- xosa1st*retexamt1 - asdfed*xdedfed*dedfit1) ;
					
							xstiND2 = max(0, xagi2 - itemizerSEP*xitemded2 - (1-itemizerSEP)*xstded2 - xexemptND2
								- xosa1st*retexamt2 - asdfed*xdedfed*dedfit2) ;
							if xstiND1>=xstiND2 then do ;
								xexemptDISC1 = min(xexemptDISC, xstiND1-xstiND2) ;
								xexemptDISC2 = 0 ;
								xexemptSPLIT = max(0, xexemptDISC - xexemptDISC1)/2 ;
							end ;
							else do ;
								xexemptDISC1 = 0 ;
								xexemptDISC2 = min(xexemptDISC, xstiND2-xstiND1) ;
								xexemptSPLIT = max(0, xexemptDISC - xexemptDISC2)/2 ;
							end ;
                        	xsti1=max(0, xstiND1 - xexemptDISC1 - xexemptSPLIT) ;
                        	xsti2=max(0, xstiND2 - xexemptDISC2 - xexemptSPLIT);
                	end;
				end ;

                /************************************************************************* 
				* xsti for extra tax or credit that is a function of state tax liability *
				**************************************************************************/
                else if xtaxtype="liabtax" or xtaxtype="liabcred" then do ;
                        xsti=max(StaxAGC,0) ;
						if separate=1 then do ;
							xsti1=max(StaxAGC1,0) ;
							xsti2=max(StaxAGC2,0) ;
						end ;
				end;
                /************************************************************************* 
				* xsti for extra tax on capital income									 *
				**************************************************************************/
                else if (xbase="cg" or xbase="div" or xbase="di" or xbase="dcg"
                        or xbase="dcgi") then do ;
						xsti = max(0, xagi - xexempt) ;
						if separate=1 then do;
							xsti1= max(0, xagi1 - xexempt/2) ;
                        	xsti2= max(0, xagi2 - xexempt/2) ;
						end;
                end;

                /*********************************************************
                * State tax liability, extra tax calculation (xtaxs)     *
                **********************************************************/
                /* Extra tax or credit following standard bracket and rate
                   approach */
 
                if xtaxtype="paratax" or xtaxtype="paracred" or xtaxtype="maxtax"
                or xtaxtype="liabtax" or xtaxtype="liabcred" then do;
                        xcredit=0;
                        %bracketreader(xsti, xtaxs, xrate, xbracket, xbracknum) ;
                        if separate=1 then do;
                                %bracketreader(xsti1, xtaxs1, xrate, xbracket, xbracknum) ;
                                %bracketreader(xsti2, xtaxs2, xrate, xbracket, xbracknum) ;
                        end;
                        else do;
                        end;
                        if xtaxtype="liabcred" or xtaxtype="paracred" then do;
                                xcredit=xtaxs;
                                xtaxs=0;
								if separate=1 then do ;
									xcredit1=xtaxs1 ;
									xcredit2=xtaxs2 ;
									xtaxs1=0 ;
									xtaxs2=0 ;
								end; 
                        end;
                        if xnotaxflr>0 and Fagi<xnotaxflr then do ;
							xtaxs=0; xtaxs1=0 ; xtaxs2=0 ;
						end ;
                end;

                /*****************************************
                * General credits in extra state tax     *
                ******************************************/
                xgencred = xcrpercap*(1+(filertype="m")+deps) + xcrreturn
                        + (xcred_dep * deps) + (xcred_age * agenum) ;

					/* married flining separately */
					if separate=1 and credalloc>0 then do ;
        				xgencred1 = xcrpercap*(1+deps1) + (xcrreturn/2)
                        	+ (xcred_dep * deps1) + (xcred_age * (agex>=65)) ;
        				xgencred2 = xcrpercap*(1+deps2) + (xcrreturn/2)
                        	+ (xcred_dep * deps2) + (xcred_age * (agespx>=65)) ;
					end ;
					else if separate=1 then do ;
						xgencred1=xgencred*min(0,max(0,(xtaxs1/max(xtaxs1+xtaxs2,1)))) ; 
						xgencred2=xgencred*(1- min(0,max(0,(xtaxs1/max(xtaxs1+xtaxs2,1)))) ) ;
					end ;
					else do ;
						xgencred1=0 ; xgencred2=0 ;
					end ;

				/********************************************************************
                * dagi, diagi, agicred			                                    *
                * Rate depends on federal AGI class, rate is then applied to whole	*
                * base, not just amount in bracket                                  *
				* (warning: this is a source of significant nothces)				*
				*********************************************************************/
                if xtaxtype="dagi" or xtaxtype="diagi" or xtaxtype="agicred"
                then do;
						FagiPos=max(Fagi,0) ;
                        %bracketreader(FagiPos, junk, xrate, xbracket, xbracknum) ;
                        if xtaxtype="dagi" then do;
                                xtaxs=(brackmtr/100)*div;
                                xcredit=0;
                        end;
                        else if xtaxtype="diagi" then do;
                                xtaxs=(brackmtr/100)*(div+int);
                                xcredit=0;
                        end;
                        else if xtaxtype="agicred" and statename ne "ca" then do;
                                xcredit=(brackmtr/100)*StaxAGC;
                                xtaxs=0;
								if xagicrmax>0 then xcredit=min(xcredit,xagicrmax) ;
								/* Note: CT agicred applies to tax liability before minimum tax,
								   but this is already taken care of using "mintaxapp" */
                        end;
						else if xtaxtype="agicred" and statename = "ca" then do ;
                                xcredit=(brackmtr/100)*max(0,StaxAGC-StaxMIN);
                                xtaxs=0;
								if xagicrmax>0 then xcredit=min(xcredit,xagicrmax) ;
						end ;
                end;
        end;
        else do;
        	xtaxs=0;
			xtaxs1=0;
			xtaxs2=0;
            xcredit=0;
			xcredit1=0;
			xcredit2=0;
            xgencred=0;
			xgencred1=0;
			xgencred2=0;
		end;
		if separate=1 then do ;
			if xcredit1=. then xcredit1=0 ;
			if xcredit2=. then xcredit2=0 ;
			if xgencred1=. then xgencred1=0;
			if xgencred2=. then xgencred2=0;
		end ;

		/*******************************************************************
		State maximum tax on personal service income (NY 1978-1986)
		********************************************************************/
		if xtaxtype = "maxei" then do ;
			if psincome=-1 and psded=-1 then xsti = min(1,max(0,(nflabinc+pension-busex-movex)/max(agi,1)))*sti ;
			else if psded=-1 then xsti = min(1,max(0,(psincome-busex-movex)/max(agi,1)))*sti ;
			else if psincome=-1 then xsti = min(1,max(0,(nflabinc+pension-psded)/max(agi,1)))*sti ;
			else xsti = min(1,max(0,(psincome-psded)/max(agi,1)))*sti ;

			if xsti>xb2 then do ;
	            %bracketreader(xsti, xcredit, xrate, xbracket, xbracknum) ;
			end ;
	
			if separate=1 then do ;
				if psincome=-1 or psded=-1 then do ;
					xsti1 = min(1,max(0,(nflabinc1+pension1-busex1-movex1)/max(agi1,1)))*sti1 ;
					xsti2 = min(1,max(0,(nflabinc2+pension2-busex2-movex2)/max(agi2,1)))*sti2 ;
				end ;
				else do ;
					psincome1 = min(1,max(0,(nflabinc1+pension1)/max(nflabinc+pension,1)))*psincome ;
					psincome2 = min(1,max(0,(nflabinc2+pension2)/max(nflabinc+pension,1)))*psincome ;
					psded1 = min(1,max(0,(busex1+movex1)/max(busex+movex,1)))*psded ;
					psded2 = min(1,max(0,(busex2+movex2)/max(busex+movex,1)))*psded ;
					xsti1 = min(1,max(0,(psincome1-psded1)/max(agi1,1)))*sti1 ;
					xsti2 = min(1,max(0,(psincome2-psded2)/max(agi2,1)))*sti2 ;
				end ;

				if xsti1>xb2 then do ;
	            	%bracketreader(xsti1, xcredit1, xrate, xbracket, xbracknum) ;
				end ;

				if xsti2>xb2 then do ;
		            %bracketreader(xsti2, xcredit2, xrate, xbracket, xbracknum) ;
				end ;
			end ;
		end ;

		/*********************************************
		LIABCRED2
		Kentucky family size credit, 2005 - 
		**********************************************/
		/*
		if xtaxtype = "liabcred2" then do ;
			if (1 + (filertype="m") + kids2) = 1 then do ;
				if agi<xb1 then xcredit = max(0,StaxAMIN-gencred) ;
				else if agi<xb2 then xcredit = ((agi-xb1)/(xb2-xb1))*max(0,StaxAMIN-gencred) ;
				else xcredit = 0 ;
			end ;
			else if (1 + (filertype="m") + kids2) = 2 then do ;
				if agi<xb3 then xcredit = max(0,StaxAMIN-gencred) ;
				else if agi<xb4 then xcredit = ((agi-xb3)/(xb4-xb3))*max(0,StaxAMIN-gencred) ;
				else xcredit = 0 ;
			end ;
			else if (1 + (filertype="m") + kids2) = 3 then do ;
				if agi<xb5 then xcredit = max(0,StaxAMIN-gencred) ;
				else if agi<xb6 then xcredit = ((agi-xb5)/(xb6-xb5))*max(0,StaxAMIN-gencred) ;
				else xcredit = 0 ;
			end ;
			else if (1 + (filertype="m") + kids2) >= 4 then do ;
				if agi<xb7 then xcredit = max(0,StaxAMIN-gencred) ;
				else if agi<xb8 then xcredit = ((agi-xb7)/(xb8-xb7))*max(0,StaxAMIN-gencred) ;
				else xcredit = 0 ;
			end ;
			if separate = 1 then do ;
				xcredit1 = xcredit*max(0,min(1,max(0,StaxAMIN1-gencred1)/max(1,StaxAMIN-gencred))) ;
				xcredit2 = xcredit - xcredit1 ;
			end ;
		end ;
		*/

		/********************************************************************
		* Calculate minimum tax for states where it applies after extra tax *
		*********************************************************************/
		if mintaxapp=3 then do ;
			StaxMIN = max(0,StaxTAMT-StaxNORM) ;
			xStaxMIN = max(0,StaxTAMT-xtaxs) ;
			if separate=1 then do ;
				StaxMIN1 = max(0,StaxTAMT1-StaxNORM1);
				StaxMIN2 = max(0,StaxTAMT2-StaxNORM2);
				xStaxMIN1 = max(0,StaxTAMT1-xtaxs1);
				xStaxMIN2 = max(0,StaxTAMT2-xtaxs2);
			end;
		end ;
		else do ;
			xStaxMIN=0 ;
			if separate=1 then do ;
				xStaxMIN1=0 ;
				xStaxMIN2=0 ;
			end ;
		end ;
		if mintaxapp=4 then StaxMIN = max(0,StaxTAMT-max(0,StaxAMIN-xcredit-lowcred)) ;
		else if mintaxapp=5 then StaxMIN = max(0,StaxTAMT - 
			max(0,StaxAMIN-gencred-itemcred-retcred-lowcred-kcarecred*(1-kcrefshare))) ; 
		if mintaxapp=4 or mintaxapp=5 then StaxMINac=StaxMIN ;
			else StaxMINac=0;

        /*****************************************
        * Tax liability after extra tax (StaxAX) *
        ******************************************/
        if xtaxtype ne "maxtax" then do ;
                StaxAX=max(0,max(0,StaxAMIN + StaxMINac 
					-(retcred+lowcred+gencred+itemcred+marcred+(1-kcrefshare)*kcarecred)
					-xcredit)
                    +max(0,xtaxs-xgencred
                    -xosa1st*max(0,(retcred+lowcred+gencred+itemcred+marcred+(1-kcrefshare)*kcarecred)-StaxAMIN)))
                    -retcredref-lowcredref-kcrefshare*kcarecred;
				if separate=1 then do ;
					StaxAX1=max(0,max(0,StaxAMIN1-(lowcred1+gencred1+(1-kcrefshare)*kcarecred1)
						-xcredit1)
                        +max(0,xtaxs1-xgencred1
                        -xosa1st*max(0,(lowcred1+gencred1+(1-kcrefshare)*kcarecred1)-StaxAMIN1))) 
						-retcredref-lowcredref-kcrefshare*kcarecred1 ;
   					StaxAX2=max(0,max(0,StaxAMIN2-(lowcred2+gencred2+(1-kcrefshare)*kcarecred2)
						-xcredit2)
                        +max(0,xtaxs2-xgencred2
                        -xosa1st*max(0,(lowcred2+gencred2+(1-kcrefshare)*kcarecred2)-StaxAMIN1))) 
						-kcrefshare*kcarecred2 ;                  
				end ;
		end ;
        else if xtaxtype = "maxtax" then do ;
                StaxAX=max(0,min(StaxAMIN + (mintaxapp=3)*StaxMIN, xtaxs + (mintaxapp=3)*xStaxMIN)
					-retcred-lowcred-gencred-itemcred-marcred-(1-kcrefshare)*kcarecred-xcredit)
					-retcredref-lowcredref-kcrefshare*kcarecred;
				if separate=1 then do ;
					StaxAX1=max(0,min(StaxAMIN1 + (mintaxapp=3)*StaxMIN1, xtaxs1 + (mintaxapp=3)*xStaxMIN1)
						-lowcred1-gencred1-(1-kcrefshare)*kcarecred1-xcredit1)
						-retcredref-lowcredref-kcrefshare*kcarecred1;
					StaxAX2=max(0,min(StaxAMIN2 + (mintaxapp=3)*StaxMIN2, xtaxs2 + (mintaxapp=3)*xStaxMIN2)
						-lowcred2-gencred2-(1-kcrefshare)*kcarecred2-xcredit2)
						-kcrefshare*kcarecred2;
				end ;
		end ;


		/********************************************************************************
		* Extra tax calculations for Arkansas											*
		* Implements choice between pension exclusion and credits, and choice between   *
		* low-income table and regular tax.												*
		*********************************************************************************
		* Step 1: re-calculate Arkansas tax with retirement income exclusion, and		*
		* without working taxpayer credit or elderly credit 							*
		*********************************************************************************/
		if retextype=14 and pension>0 then do ;
			retexamt=min(pension,retex)*agequal ;
			xsti = max(0,Sti-retexamt) ;
	 		%bracketreader(xsti, xtaxs, rate, bracket, bracknum) ;
			if separate=1 then do ;
               	if retextype=14 then retexamt1=min(pension1,retex/2)*agequal1 ;
				xsti1 = max(0,Sti1-retexamt1) ;
		 		%bracketreader(xsti1, xtaxs1, rate, bracket, bracknum) ;		
               	if retextype=14 then retexamt2=min(pension2,retex/2)*agequal2 ;
				xsti2 = max(0,Sti2-retexamt2) ;
		 		%bracketreader(xsti2, xtaxs2, rate, bracket, bracknum) ;		
			end ;
        	/**************************************************************************
        	*    Re-calculate alternative capital gains treatment with 			      *
        	*    retirement income exclusion. (See cgmax2 above). 					  *
			*    xtaxs, xtaxs1, and xtaxs2 are replaced where appropriate.			  *
        	***************************************************************************/
	        if sptx="cgmax2" and ltcg>0 and xsti>b6 then do;
    	    	if (xsti-(1-(cgexpct/100))*ltcg)>=b6 then do;
        	    	StiEXCG=max(0, xsti-(1-(cgexpct/100))*ltcg);
            	    %bracketreader(StiEXCG, StaxEXCG, rate, bracket, bracknum) ;
                	xtaxs = StaxEXCG + (sptxrate/100)*ltcg*(1-(cgexpct/100));
	            end;
	            else if (xsti-(1-(cgexpct/100))*ltcg) < b6 then do;
	            	%bracketreader(b6, Staxb6, rate, bracket, bracknum) ;
	                xtaxs = Staxb6 + (sptxrate/100)*(xsti-b6) ;
	            end;
	            if separate=1 and (xsti1>b6 or xsti2>b6) then do;
	            	StiEXCG1=max(0,xsti1-ltcg1*(1-(cgexpct/100)));
	                StiEXCG2=max(0,xsti2-ltcg2*(1-(cgexpct/100)));
	                if (xsti1-ltcg1)>=b6 then do;
	                	%bracketreader(StiEXCG1, StaxEXCG1, rate, bracket, bracknum) ;
	                    xtaxs1=StaxEXCG1+(sptxrate/100)*ltcg1*(1-(cgexpct/100));
	                end;
	                else if xsti1 > b6 and (xsti1-ltcg1)<b6 then do;
	                	%bracketreader(b6, Staxb61, rate, bracket, bracknum) ;
	                    xtaxs1=Staxb61+(sptxrate/100)*(xsti1-b6);
	                end;
	                if (xsti2-ltcg2)>=b6 then do;
	                	%bracketreader(StiEXCG2, StaxEXCG2, rate, bracket, bracknum) ;
	                	xtaxs2=StaxEXCG2+(sptxrate/100)*ltcg2*(1-(cgexpct/100));
	                end;
	                else if xsti2 > b6 and (xsti2-ltcg2)<b6 then do;
	                	%bracketreader(b6, Staxb62, rate, bracket, bracknum) ;
	                    xtaxs2=Staxb62+(sptxrate/100)*(xsti2-b6);
	                end;
	            end;
	        end;
	        /******************************************************************
	        * Calculate tax liability after extra tax for Arkansas (StaxAX)   *
			* Applies retirement income exclusion, and eliminates age credit  *
			* and working family tax credit (lowcred)						  *
	        *******************************************************************/
	        StaxAX = max(0, xtaxs-gencred-itemcred-retcred-marcred-kcarecred*(1-kcrefshare)+agenum*cred_age)
            	-retcredref-kcarecred*kcrefshare;
			if StaxAGC<StaxAX then do ;
				StaxAX=StaxAGC ;
				retexamt=0 ;
			end ;
			else Sti=xsti ;
			if separate=1 then do ;
				StaxAX1 = max(0, xtaxs1-gencred1-kcarecred1*(1-kcrefshare)+(cred_age*(agex>=65)))
					-kcarecred*kcrefshare ;
				if StaxAGC1<StaxAX1 then do ;
					StaxAX1=StaxAGC1 ;
					retexamt1=0 ;
				end ;
				else Sti1=xsti1 ;
				StaxAX2 = max(0, xtaxs2-gencred2-kcarecred2*(1-kcrefshare)+(cred_age*(agespx>=65)))
					-kcarecred*kcrefshare ;
				if StaxAGC2<StaxAX2 then do ;
					StaxAX2=StaxAGC2 ;
					retexamt2=0 ;
				end ;
				else Sti2=xsti2 ;	
			end ;
		end ;
		/********************************************************************************
		* Step 2: Calculate tax based on Arkansas low-income tax table where applicable *
		*********************************************************************************/
		if xtaxtype = "lowtab1" and income < (xb2 + min(deps, 2)*xex_dep) then do ;
			if income < (xb1 + min(deps, 2)*xex_dep) then xtaxs=0 ;
			else xtaxs = ((int((income+10)/10)*10 - (xb1 + min(deps, 2)*xex_dep))/(xb2-xb1))*(xcrreturn + min(deps,2)*xex_dep) ;
			if xtaxs<StaxAX then StaxAX = xtaxs ;
		end ;
		if xtaxtype = "lowtab2" and income < (xb2 + ((filertype="m")*(deps>=2))*xb4) then do ;
			xsti = max(0,agi-stded) ;
	 		%bracketreader(xsti, xtaxs, rate, bracket, bracknum) ;
			xtaxs=max(0,xtaxs-lowcred) ;
			if income < (xb1 + ((filertype="m")*(deps>=2))*xb3) then xgencred=xtaxs ;
			else xgencred = xtaxs*(1-((income-(xb1 + ((filertype="m")*(deps>=2))*xb3))
					/((xb2 + ((filertype="m")*(deps>=2))*xb4)-(xb1 + ((filertype="m")*(deps>=2))*xb3)))) ;
			xtaxs=max(0, xtaxs-xgencred-gencred-itemcred-retcred-marcred-kcarecred*(1-kcrefshare))
            	-retcredref-kcarecred*kcrefshare;
			if xtaxs<StaxAX then StaxAX = xtaxs ;
		end ;



        /***************************************************
        *  State earned income credits                     *
        ****************************************************/
        if eicstate1>0 then do;
                /* % of fed, refundable */
                if eictypestate=0 then do ;
                	eicstateref = (eicstate1/100)*Feic ;
					eicstatenoref = 0 ;
				end ;
                /* % of fed, non-refundable */
                else if eictypestate=1 then do ;
					eicstateref=0 ;
                    eicstatenoref = min(max(StaxAX,0),(eicstate1/100)*Feic) ;
				end ;
                /* % of fed, partly refundable, MD */
                else if eictypestate=2 then do ;
					eicstatenoref = (eicstate1/100)*Feic ;
                    if eicstatenoref>=StaxAMIN then
						eicstateref = max(0,(eicstate2/100)*Feic - StaxAMIN) ;
					else eicstateref=0 ;
				end ;
                /* % of fed, refundable, income ceiling */
                else if eictypestate=3 then do ;
					if agi<eicstate2 then eicstateref = (eicstate1/100)*Feic;
						else eicstateref = 0 ;
					eicstatenoref = 0 ;
				end ;
                /* % of fed, varies number of qualifying children (Wisconsin) */
                else if eictypestate=4 then do;
                    if kids2=1 then eicstateref=(eicstate1/100)*Feic;
                    else if kids2=2 then eicstateref=(eicstate2/100)*Feic;
                    else if kids2>2 then eicstateref=(eicstate3/100)*Feic;
					else eicstateref=0 ;
					eicstatenoref=0 ;
                end;
				else if eictypestate=5 then do ; /* Rhode Island  */
					eicstatenoref = (eicstate1/100)*Feic ;
					eicstateref = (eicstate2/100)*max(0,(eicstate1/100)*Feic-StaxAX) ;
				end ;
				else if eictypestate=6 and Feic>0 then do ; /* Minnesota 1998 - present */
					eicstatenoref=0 ;
					if kids2=0 then eicstateref=(eicstate1/100)*Feic ;
					else if kids2=1 then eicstateref=max(0,
							(r10/100)*min(earnedinc,b10)
							+(r11/100)*min(max(0,earnedinc-b11),b12-b11)
							-(r12/100)*max(0,max(earnedinc,agi)-b13) ) ;
					else if kids2>1 then eicstateref=max(0,
							(r20/100)*min(earnedinc,b20)
							+(r21/100)*min(max(0,earnedinc-b21),b22-b21)
							-(r22/100)*max(0,max(earnedinc,agi)-b23) ) ;
				end ;
				/* % of fed, non-refundable, cannot take both EIC and lowcred. VA 2006 - */
                else if eictypestate=7 and Feic>0 then do ;
					eicstateref=0 ;
                    eicstatenoref = min(max(StaxAX,0),max(0,(eicstate1/100)*Feic-lowcred)) ;
				end ;
				else do ;
					eicstateref=0 ;
					eicstatenoref=0 ;
				end ;
        end;
		else do ;
			eicstateref=0 ;
			eicstatenoref=0 ;
		end ;

		/***************************************************
		*  Calculate final state tax liability			   *
        *  taxs -- state tax liability after everything    *
		*  (except circuit breaker credits, which are	   *
		*  computed later and allowed to modify taxs)	   *
		****************************************************/
		taxs=StaxAX-min(StaxAX,eicstatenoref)-eicstateref+(mintaxapp=2)*StaxMIN ;

		if separate=0 then Ssepfiler=0 ;
		else if separate=1 then do ;
			taxs1 = StaxAX1 + (mintaxapp=2)*StaxMIN1 - (min(StaxAX1,eicstatenoref) + eicstateref )*
				min(1,max(0,(StaxAX1/max(StaxAX1+StaxAX2,1)))) ;
			taxs2 = StaxAX2 + (mintaxapp=2)*StaxMIN2 - (min(StaxAX2,eicstatenoref) + eicstateref )*
				(1- min(1,max(0,(StaxAX1/max(StaxAX1+StaxAX2,1)))) ) ;
			if ((taxs1+taxs2)<taxs and (sepdis ne 2)) 
				or (exalloc=5 or exalloc=7) then do ;
				Ssepfiler=1 ;
				taxs = taxs1+taxs2 ; 
				itemizer_s = itemizerSEP ;
				agi = agi1+agi2 ;
				sti = sti1+sti2 ;
				retexamt=retexamt1+retexamt2 ;
				miscex=miscex1+miscex2 ;
				StaxNORM=StaxNORM1+StaxNORM2 ;
				sptxliab=sptxliab1+sptxliab2 ;
				sptx2liab=sptx2liab1+sptx2liab2 ;
				StaxALTCG=StaxALTCG1+StaxALTCG2 ;
				StaxASP=StaxASP1+StaxASP2 ;
				StaxAMIN=StaxAMIN1+StaxAMIN2 ;
				if (mintaxtype=1 or mintaxtype=7) then StaxMIN=StaxMIN1+StaxMIN2 ;
				gencred=gencred1+gencred2 ;
				lowcred=lowcred1+lowcred2 ;
				StaxAGC=StaxAGC1+StaxAGC2 ;
				xtaxs=xtaxs1+xtaxs2 ;
				xcredit=xcredit1+xcredit2 ;
				StaxAX=StaxAX1+StaxAX2 ;
			end ;
			else do ;
				Ssepfiler=0 ;
				taxs=StaxAX-min(StaxAX,eicstatenoref)-eicstateref+(mintaxapp=2)*StaxMIN ;
			end ;
		end ;

		/***************************************************
		*  Calculate local tax liability				   *
        *  and re-calculate state liability	to    		   *
		*  include any local tax						   *
		****************************************************/		
		localtax = 0 ;
		if ( &local > 0 ) then do ;
			if localtype=1 then localtax=(localrate/100)*taxs ;
			else if localtype=2 then localtax=(localrate/100)*income ;
			else if localtype=3 then localtax=(localrate/100)*
				(wagsal1+wagsal2+businc1+businc2+farminc1+farminc2) ;
			if ( &local = 2 ) then do ;
				localtax = localtax*((statename="md")+(statename="pa")+(statename="in")) ;
			end ;				
			taxs = taxs + localtax ;
		end ;
end;

/***********************************************************
*  State tax that is a percentage of federal tax liability *
************************************************************/
else if (taxtype="pctfed" or taxtype="pctfed2" 
		 or taxtype="pctfed3" or taxtype="pctfed4") then do;

		if taxtype ne "pctfed4" then pctfedbase=taxf_S ;
		else pctfedbase = (Fdtxliab_bc_S + FtaxMIN_S + Famt_S) ;

        %bracketreader(pctfedbase, taxs, rate, bracket, bracknum) ;
        SmtrNORM=(brackmtr/100)*FmtrNORM_S;
        SmtrNORM2=SmtrNORM;

		/* Other necessary variables that are equivalent to federal values */
        agi=Fagi;
		chlimbind = Fchlimbind ;

        /* State general credits */
        gencred = crpercap*(1+(filertype="m")+deps) + crreturn
                        + (cred_dep * deps) + (cred_age * agenum) ;
        if crpercap>0 then crednum=(1+(filertype="m")+deps);
        if crreturn>0 then crednum=crednum+1;
        if cred_dep>0 then crednum=crednum+deps;
        if cred_age>0 then crednum=crednum+agenum;

		/**************************************** 
		Low-income credits (VT 1969-1993) 
		*****************************************/
			/* Number of taxpayers over qualifying age threshhold */
			if filertype="m" then agequal=((agex>=retexage)+(agespx>=retexage))/2 ;
        	else if (filertype="s" or filertype="h") then agequal=(agex>=retexage) ;

            /* Refundable per capita credit (VT 1969-1973) */
           	if lowtype=8 and agex>lowminage then do;
            	if lowph1=0 then lowcredref=(low*(1+(filertype="m")+deps)+loweldamt*agenum)
                	*max(0,1-(max(agi,0)/max(1,lowph2+lowphdep*deps)));
            	else if agi<(lowph1+lowphdep*deps)
            		then lowcredref=low*(1+(filertype="m")+deps) + loweldamt*agenum;
            	else if lowph1=lowph2 then lowcredref=0;
            	else lowcredref=(low*(1+(filertype="m")+deps)+loweldamt*agenum)
            		*max(0,1-((max(agi,0)-(lowph1+lowphdep*deps))/(lowph2-lowph1)));
                lowcred=0;
            end;

		    /* Refundable credit, VT 1974-1993 */
            else if lowtype=3 then do;
             	if lowph1=0 then lowcredref=(low+(lowdepamt*deps)+(loweldamt*agenum))
                   	*(1-(max(agi,0)/(lowph2+lowphdep*deps)));
            	else if agi<(lowph1+lowphdep*deps)
                   	then lowcredref=low+(lowdepamt*deps)+(loweldamt*agenum);
                else if lowph1=lowph2 then lowcredref=0;
                else lowcredref=(low+(lowdepamt*deps)+(loweldamt*agenum))
                  	*max(0,1-((max(agi,0)-(lowph1+lowphdep*deps))/(lowph2-lowph1)));
                lowcredref=lowcredref*agequal;
                lowcred=0;
            end;
			else do ;
				lowcredref=0 ;
				lowcred=0 ;
			end ;

		/********************************* 
		Retirement income credit 
		**********************************/
		/* Nebraska 1981-1986 */
		if taxtype = "pctfed4" then retcred = (pctfdeldcr/100)*Feldcred ;
		/* Vermont, 1971-1991 */
		else if retextype=16 then do ;
        	if agi<retex then retcred=taxs ;
            if taxs>retph1 then
        		retcred=max(0, retcred-((taxs-retph1)/max(1,retph2-retph1))*retcred);
			if (retexage>0 and agenum=0) then retcred=0 ;
        end;
		/* All others */
		else retcred=0 ;

        /* State tax liability after credits */
		if (taxtype ne "pctfed3") then taxs=taxs-max(0,min(gencred+retcred+lowcred,taxs))-lowcredref ;
		else taxs=max(0,taxs-(gencred+retcred)) ;

		/* Vermont maximum tax, 1969-1973 */
		if sptx="vtmax" then do ;
	        if max( 0,taxs + (taxf_S-taxfns) ) > (sptxrate/100)*( max(Fagi,0)+Fexltcg )
				then taxs = (sptxrate/100)*( max(Fagi,0)+Fexltcg ) ;
		end ;
end;


%macro circuit ; 
/***********************************************************
*  STATE CIRCUIT BREAKER PROPERTY TAX CREDITS 			   *
************************************************************/
if cbtype>0 and ( &cbinclude > 0 ) then do ;

	/* initialize certain variables to zero */
	propcred=0 ; /* property tax credit */
	propbase=0 ; /* property tax subject to credit */
	rentbase=0 ; /* rent subject to credit */
	floor=0 ; /* only property tax and rent in excess of the floor qualifies */
	pc=0 ; /* property tax credit before income-based phase-out */
	cbmax=0 ; /* maximum allowable credit */
	cbmin=0 ; /* minimum credit */
	cbpct=0 ; /* credit as a percentage of property tax */
	agexx = max(agex,agespx) ; /* generally, older of two spouses can qualify the couple */

	/* Income definition used in circuit breaker calculations */
	if cbincdef=1 then cbincome=max(income,0) ;
	else if cbincdef=2 then cbincome = max(income-ssben1-ssben2,0) ;
	else if cbincdef=3 then cbincome = max(income-min(othcg1,0)-min(othcg2,0),0) ;
	else if cbincdef=4 then do ;
		if agexx>=cbage then cbincome = max(income,0) ;
		else cbincome = max(agi,0) ;
	end ;
	else if cbincdef=5 then cbincome = max(agi,0) ;
	else if cbincdef=6 then cbincome = max(income-(ltcg1+ltcg2+othcg1+othcg2)-medexp,0) ;
	else if cbincdef=7 then cbincome = max(income-cbincval1*deps,0) ;
	else if cbincdef=8 then cbincome = 
		max(0, income-Fexpercap*(agenum + cbincval1*(deps>0) + cbincval2*(deps>1)
			+ cbfloor3*(deps>2) + cbfloor4*(deps>3) + max(0,deps-4))
			-(stateyear>1988)*(min(othcg1,0)+min(othcg2,0))) ;
	else if cbincdef=9 then cbincome = 
		max(0, income-max(cbincval1,(cbincval2/100)*(pension1+pension2+ssben1+ssben2))) ;
	else if cbincdef=10 then cbincome = max(0, income-medexp) ;
	else if cbincdef=11 then cbincome = max(0, income-min(proptax,cbincval1)) ;
	else if cbincdef=12 then cbincome = max(0, income-cbincval1*agenum) ;
	else if cbincdef=13 then cbincome = max(0, income-.5*(ssben1+ssben2)) ; 
	else if cbincdef=14 then cbincome = max(income-cbincval1*(deps+agenum),0) ; 
	else cbincdef=max(0,income) ;

	/******************************************* 
	* CALCULATE PROPERTY TAX CREDIT (propcred) *
	********************************************/

	/*** CBTYPE 1, 2, 10, 11, 15, 21 (CA 1967-76, 1981-2004, CO, IA , KS 1973-2004,
	ME 1971-88, MI, MN 1967-74, MO, NV, ND, OK, PA 1971-79 and 1991-2004, VT 1969-72,
	AZ, IN, ME 1989-present, MA, RI, WI 1973-present) ***/	
	if cbtype=1 or cbtype=2 or cbtype=10 or cbtype=11 or cbtype=15 or cbtype=21 or cbtype=24 then do ;

		if cbmaxhome>0 and homeval>0 then propbase=proptax*(min(cbmaxhome,homeval)/homeval) ;
			else propbase=proptax ;
		if cbmaxrent>0 and rentpay>0 then rentbase=min(rentpay,cbmaxrent) ;
			else rentbase=rentpay ;
		if cbmaxcr2>0 then propbase=min(propbase,cbmaxcr2) ;
		if cbmaxcr1>0 and cbtype ne 11 then cbmax=cbmaxcr1 ;
			else cbmax=0 ;
		if cbtype=11 and cbincome<cbthresh5 then cbmin=cbmaxcr1 ;
			else cbmin=0 ;

		if agexx>=cbage then do ;

			if cbmaxcr2>0 then rentbase=min(rentbase*(cbrenteq/100),cbmaxcr2) ;
				else rentbase=rentbase*(cbrenteq/100) ;

			if max(cbfloor1,cbfloor2)>0 and (cbtype ne 24) then do ;
				if cbincome>=cbthresh4 and (cbtype ne 21) then floor=(cbfloor2/100)*cbincome ;
				else if cbincome>=cbthresh4 and cbtype = 21 then floor=(cbfloor3/100)*cbincome ;
				else if cbincome<cbthresh3 then floor=(cbfloor1/100)*cbincome ;
				else if cbthresh4>cbthresh3 then 
					floor=((cbfloor1/100)*cbincome*(cbincome-cbthresh3)/(cbthresh4-cbthresh3)) 
						+ ((cbfloor2/100)*cbincome*(cbthresh4-cbincome)/(cbthresh4-cbthresh3)) ;
				else floor=0 ;
			end ;
			else floor=0 ;

			if cbtype = 24 then do ;
				if cbincome>=cbthresh4 and (cbtype ne 21) then floor=(cbfloor2/100)*max(0,cbincome-cbthresh3) ;
				else if cbincome>=cbthresh4 and cbtype = 21 then floor=(cbfloor3/100)*max(0,cbincome-cbthresh3) ;
				else if cbincome<cbthresh3 then floor=(cbfloor1/100)*max(0,cbincome-cbthresh3) ;
				else if cbthresh4>cbthresh3 then 
					floor=(((cbfloor1/100)*(cbincome-cbthresh3)/(cbthresh4-cbthresh3)) 
						+ ((cbfloor2/100)*(cbthresh4-cbincome)/(cbthresh4-cbthresh3)))
						* max(0,cbincome-cbthresh3) ;
				else floor=0 ;
			end ;

			if cbmax>0 then pc = min((cbpct1/100)*max(propbase+rentbase-floor,0),cbmax) ;
				else pc = max((cbpct1/100)*max(propbase+rentbase-floor,0),cbmin) ;
			
			if cbincome<cbthresh1 then propcred = pc ;
			else if cbincome>=cbthresh2 then propcred = 0 ;
			else if cbthresh2>cbthresh1 then
				propcred = pc*(cbincome-cbthresh1)/(cbthresh2-cbthresh1) ;
			else propcred=0 ;

		end ;
 
		else if agexx<cbage and xcbpct1>0 and (cbtype ne 10) and (cbtype ne 15) 
			and (cbtype ne 20) then do ;

			if cbmaxcr2>0 then rentbase=min(rentbase*(xcbrenteq/100),cbmaxcr2) ;
				else rentbase=rentbase*(xcbrenteq/100) ;

			if max(xcbfloor1,xcbfloor2)>0 then do ;
				if cbincome>=xcbthresh4 then floor=(xcbfloor2/100)*cbincome ;
				else if cbincome<xcbthresh3 then floor=(xcbfloor1/100)*cbincome ;
				else if xcbthresh4>xcbthresh3 then 
					floor=((xcbfloor1/100)*cbincome*(cbincome-xcbthresh3)/(xcbthresh4-xcbthresh3)) 
						+ ((xcbfloor2/100)*cbincome*(xcbthresh4-cbincome)/(xcbthresh4-xcbthresh3)) ;
				else floor=0 ;
			end ;
			else floor=0 ;

			if xcbmaxcr1>0 then pc = min((xcbpct1/100)*max(propbase+rentbase-floor,0),xcbmaxcr1) ;
				else pc = (xcbpct1/100)*max(propbase+rentbase-floor,0) ;
			
			if cbincome<xcbthresh1 then propcred = pc ;
			else if cbincome>=xcbthresh2 then propcred = 0 ;
			else if xcbthresh2>xcbthresh1 then
				propcred = pc*(cbincome-xcbthresh1)/(xcbthresh2-xcbthresh1) ;
			else propcred=0 ;

		end ;
		else propcred=0 ;

		if cbtype=2 and cbthresh5>0 and homeval>cbthresh5 then propcred=0 ; /* applies in AZ only */

	end ;

	/*** CBTYPE 3 AR, CT 1973-84, ID, NY, OR 1971-72 ***/
	else if cbtype=3 then do ;

		if cbmaxhome>0 and homeval>0 then propbase=proptax*(min(cbmaxhome,homeval)/homeval) ;
			else propbase=proptax ;
		if cbmaxrent>0 and rentpay>0 then rentbase=min(rentpay,cbmaxrent) ;
			else rentbase=rentpay ;

		if agexx>=cbage then do ;

			rentbase=rentbase*(cbrenteq/100) ;

			if max(cbfloor1,cbfloor2)>0 then do ;
				if cbincome>=cbthresh4 then floor=(cbfloor2/100)*cbincome ;
				else if cbincome<cbthresh3 then floor=(cbfloor1/100)*cbincome ;
				else if cbthresh4>cbthresh3 then 
					floor=((cbfloor1/100)*cbincome*(cbincome-cbthresh3)/(cbthresh4-cbthresh3)) 
						+ ((cbfloor2/100)*cbincome*(cbthresh4-cbincome)/(cbthresh4-cbthresh3)) ;
				else floor=0 ;
			end ;
			else floor=0 ;

			pc = (cbpct1/100)*max(propbase+rentbase-floor,0) ;
			
			if cbincome<cbthresh1 then cbmax = cbmaxcr1 ;
			else if cbincome>=cbthresh2 then cbmax = cbmaxcr2 ;
			else if cbthresh2>cbthresh1 then
				cbmax = (cbmaxcr1*(cbincome-cbthresh1)/(cbthresh2-cbthresh1)) 
						+ ((cbmaxcr2/100)*(cbthresh2-cbincome)/(cbthresh2-cbthresh1)) ;
			else cbmax=0 ;

			if cbthresh5>0 and cbincome>=cbthresh5 then propcred=0 ;
				else propcred=min(pc,cbmax) ;

		end ;
 
		else if agexx<cbage and xcbpct1>0 then do ;

			rentbase=rentbase*(xcbrenteq/100) ;

			if max(xcbfloor1,xcbfloor2)>0 then do ;
				if cbincome>=xcbthresh4 then floor=(xcbfloor2/100)*cbincome ;
				else if cbincome<xcbthresh3 then floor=(xcbfloor1/100)*cbincome ;
				else if xcbthresh4>xcbthresh3 then 
					floor=((xcbfloor1/100)*cbincome*(cbincome-xcbthresh3)/(xcbthresh4-xcbthresh3)) 
						+ ((xcbfloor2/100)*cbincome*(xcbthresh4-cbincome)/(xcbthresh4-xcbthresh3)) ;
				else floor=0 ;
			end ;
			else floor=0 ;

			pc = (xcbpct1/100)*max(propbase+rentbase-floor,0) ;
			
			if cbincome<xcbthresh1 then cbmax = xcbmaxcr1 ;
			else if cbincome>=xcbthresh2 then cbmax = xcbmaxcr2 ;
			else if xcbthresh2>xcbthresh1 then
				cbmax = (xcbmaxcr1*(cbincome-xcbthresh1)/(xcbthresh2-xcbthresh1)) 
						+ ((xcbmaxcr2/100)*(xcbthresh2-cbincome)/(xcbthresh2-xcbthresh1)) ;
			else cbmax=0 ;

			if xcbthresh5>0 and cbincome>=xcbthresh5 then propcred=0 ;
				else propcred=min(pc,cbmax) ;

		end ;
		else propcred=0 ;

	end ;

	/*** CBTYPE 4 (CA 1977-80) ***/
	else if cbtype=4 then do ;

		if cbmaxhome>0 and homeval>0 then propbase=proptax*(min(cbmaxhome,homeval)/homeval) ;
			else propbase=proptax ;
		if cbmaxrent>0 and rentpay>0 then rentbase=min(rentpay,cbmaxrent) ;
			else rentbase=rentpay ;
		if cbmaxcr2>0 then propbase=min(propbase,cbmaxcr2) ;

		if proptax>0 then do ;

			if max(cbfloor1,cbfloor2)>0 then do ;
				if cbincome>=cbthresh4 then floor=(cbfloor2/100)*cbincome ;
				else if cbincome<cbthresh3 then floor=(cbfloor1/100)*cbincome ;
				else if cbthresh4>cbthresh3 then 
					floor=((cbfloor1/100)*cbincome*(cbincome-cbthresh3)/(cbthresh4-cbthresh3)) 
						+ ((cbfloor2/100)*cbincome*(cbthresh4-cbincome)/(cbthresh4-cbthresh3)) ;
				else floor=0 ;
			end ;
			else floor=0 ;

			if cbmaxcr1>0 then pc = min((cbpct1/100)*max(propbase-floor,0),cbmaxcr1) ;
				else pc = (cbpct1/100)*max(propbase-floor,0) ;
			
			if cbincome<cbthresh1 then propcred = pc ;
			else if cbincome>=cbthresh2 then propcred = 0 ;
			else if cbthresh2>cbthresh1 then
				propcred = pc*(cbincome-cbthresh1)/(cbthresh2-cbthresh1) ;
			else propcred=0 ;

		end ;
 
		if rentpay>0 and xcbpct1>0 then do ;

			if xcbmaxcr2>0 then rentbase=min(rentbase*(xcbrenteq/100),xcbmaxcr2) ;
				else rentbase=rentbase*(xcbrenteq/100) ;

			if max(xcbfloor1,xcbfloor2)>0 then do ;
				if cbincome>=xcbthresh4 then floor=(xcbfloor2/100)*cbincome ;
				else if cbincome<xcbthresh3 then floor=(xcbfloor1/100)*cbincome ;
				else if xcbthresh4>xcbthresh3 then 
					floor=((xcbfloor1/100)*cbincome*(cbincome-xcbthresh3)/(xcbthresh4-xcbthresh3)) 
						+ ((xcbfloor2/100)*cbincome*(xcbthresh4-cbincome)/(xcbthresh4-xcbthresh3)) ;
				else floor=0 ;
			end ;
			else floor=0 ;

			if xcbmaxcr1>0 then pc = min((xcbpct1/100)*max(rentbase-floor,0),xcbmaxcr1) ;
				else pc = (xcbpct1/100)*max(rentbase-floor,0) ;
			
			if cbincome<xcbthresh1 then propcred = propcred + pc ;
			else if cbincome>=xcbthresh2 then propcred = propcred + 0 ;
			else if xcbthresh2>xcbthresh1 then
				propcred = propcred + pc*(cbincome-xcbthresh1)/(xcbthresh2-xcbthresh1) ;
			else propcred=propcred + 0 ;

		end ;
		else propcred = propcred + 0 ;

	end ;

	/*** CBTYPE 5 (CT 1985-present) ***/
	else if cbtype=5 then do ;
		if agexx>=cbage then do ;

			/* refundable rent credit for elderly */
			if cbincome<cbthresh1 then do ;
				cbmax=cbmaxcr1 ;
				cbmin=cbmaxcr2 ;
			end ;
			else if cbincome<cbthresh2 and cbthresh2>cbthresh1 then do ;
				cbmax=cbmaxcr1*(cbincome-cbthresh1)/(cbthresh2-cbthresh1) ;
				cbmin=cbmaxcr2*(cbincome-cbthresh1)/(cbthresh2-cbthresh1) ;
			end ;
			else do ;
				cbmax=0 ; cbmin=0 ;
			end ;
			propcred=min(cbmax,max((cbpct1/100)*(cbrenteq/100)*rentpay,cbmin)) ;

			/* refundable property tax credit for elderly */
			if cbincome<cbthresh1 then do ;
				cbmax=cbthresh3 ;
				cbmin=cbthresh4 ;
			end ;
			else if cbincome<cbthresh2 and cbthresh2>cbthresh1 then do ;
				cbmax=cbthresh3*(cbincome-cbthresh1)/(cbthresh2-cbthresh1) ;
				cbmin=cbthresh4*(cbincome-cbthresh1)/(cbthresh2-cbthresh1) ;
			end ;
			else do ;
				cbmax=0 ; cbmin=0 ;
			end ;
			propcred=propcred+min(cbmax,max((cbpct2/100)*proptax,cbmin)) ;		

		end ;

		/* Elderly credits are not on income tax form */
		if &cbinclude > 2 and cbform=4 then propcred = 0 ;

		/* CT non-refundable credit for all ages */
		if xcbpct1>0 then do ;
			pc = max(min((xcbpct1/100)*proptax+(xcbrenteq/100)*rentpay,xcbmaxcr1),xcbmaxcr2) ;
			
			if cbincome<xcbthresh1 then propcred = propcred+min(pc,taxs) ;
			else if cbincome>=xcbthresh2 then propcred = 0 ;
			else if xcbthresh2>xcbthresh1 then propcred = 
				propcred + min(pc*(cbincome-xcbthresh1)/(xcbthresh2-xcbthresh1),taxs) ;
			else propcred=propcred+0 ;
		end ;		

	end ;

	/*** CBTYPE 6 (DC, MT, SD, UT 1977-81) ***/
	else if cbtype=6 then do ;
		
		if cbmaxhome>0 and homeval>0 then propbase=proptax*(min(cbmaxhome,homeval)/homeval) ;
			else propbase=proptax ;
		if cbmaxrent>0 and rentpay>0 then rentbase=min(rentpay,cbmaxrent) ;
			else rentbase=rentpay ;
		if cbmaxcr2>0 then propbase=min(propbase,cbmaxcr2) ;

		if agexx>=cbage then do ;

			if cbmaxcr2>0 then rentbase=min(rentbase*(cbrenteq/100),cbmaxcr2) ;
				else rentbase=rentbase*(cbrenteq/100) ;

			if max(cbfloor1,cbfloor2)>0 then do ;
				if cbincome>=cbthresh4 then floor=(cbfloor2/100)*cbincome ;
				else if cbincome<cbthresh3 then floor=(cbfloor1/100)*cbincome ;
				else if cbthresh4>cbthresh3 then 
					floor=((cbfloor1/100)*cbincome*(cbincome-cbthresh3)/(cbthresh4-cbthresh3)) 
						+ ((cbfloor2/100)*cbincome*(cbthresh4-cbincome)/(cbthresh4-cbthresh3)) ;
				else floor=0 ;
			end ;
			else floor=0 ;

			if cbincome<cbthresh1 then cbpct = cbpct1 ;
			else if cbincome>=cbthresh2 and cbincome<cbthresh5 then cbpct = cbpct2 ;
			else if cbincome>=cbthresh5 then cbpct=0 ;
			else if cbthresh2>cbthresh1 then
				cbpct = (cbpct1*(cbincome-cbthresh1)/(cbthresh2-cbthresh1)) 
						+ (cbpct2*(cbthresh2-cbincome)/(cbthresh2-cbthresh1)) ;
			else cbpct=0 ;

			if cbmaxcr1>0 then propcred = min((cbpct/100)*max(propbase+rentbase-floor,0),cbmaxcr1) ;
				else propcred = (cbpct/100)*max(propbase+rentbase-floor,0) ;
			
		end ;
 
		else if agexx<cbage and xcbpct1>0 then do ;

			if cbmaxcr2>0 then rentbase=min(rentbase*(xcbrenteq/100),cbmaxcr2) ;
				else rentbase=rentbase*(xcbrenteq/100) ;

			if max(xcbfloor1,xcbfloor2)>0 then do ;
				if cbincome>=xcbthresh4 then floor=(xcbfloor2/100)*cbincome ;
				else if cbincome<xcbthresh3 then floor=(xcbfloor1/100)*cbincome ;
				else if cbthresh4>xcbthresh3 then 
					floor=((xcbfloor1/100)*cbincome*(cbincome-xcbthresh3)/(xcbthresh4-xcbthresh3)) 
						+ ((xcbfloor2/100)*cbincome*(xcbthresh4-cbincome)/(xcbthresh4-xcbthresh3)) ;
				else floor=0 ;
			end ;
			else floor=0 ;

			if cbincome<xcbthresh1 then cbpct = xcbpct1 ;
			else if cbincome>=xcbthresh2 and cbincome<xcbthresh5 then cbpct = xcbpct2 ;
			else if cbincome>=xcbthresh5 then cbpct=0 ;
			else if xcbthresh2>xcbthresh1 then
				cbpct = (xcbpct1*(cbincome-xcbthresh1)/(xcbthresh2-xcbthresh1)) 
						+ (xcbpct2*(xcbthresh2-cbincome)/(xcbthresh2-xcbthresh1)) ;
			else cbpct=0 ;

			if xcbmaxcr1>0 then propcred = min((cbpct/100)*max(propbase+rentbase-floor,0),xcbmaxcr1) ;
				else propcred = (cbpct/100)*max(propbase+rentbase-floor,0) ;
		end ;

	end ;

	/*** CBTYPE 7 (HI) ***/
	else if cbtype=7 then do ;
		if agexx>=cbage and cbincome<cbthresh1 and rentpay>=cbmaxrent then 
			propcred = cbmaxcr1 + cbmaxcr2*(agenum+deps) ;	
		else if agexx<cbage and cbincome<xcbthresh1 and rentpay>=cbmaxrent then
			propcred = xcbmaxcr1 + xcbmaxcr2*(agenum+deps) ;
		else propcred=0 ;
	end ;

	/*** CBTYPE 8 (IL 1975-2004) ***/
	else if cbtype=8 and agexx>=cbage then do ;
		floor=(cbfloor1/100)*cbincome ;
		if cbincome<cbthresh1 then cbmax=(cbmaxcr1*cbincome/cbthresh1) 
			+ (cbmaxcr2*(cbthresh1-cbincome)/cbthresh1) ;
		else if cbincome<cbthresh2 then cbmax=cbmaxcr2 ;
		else if (1+(filertype="m")+deps)>=3 and cbincome<cbthresh3 then cbmax=cbmaxcr2 ;
		else cbmax=0 ;
		propcred = min(cbmax,max(0,(cbpct1/100)*proptax+(cbrenteq/100)*rentpay-floor)) ;
	end ;

	/*** CBTYPE 9 (IL 1972-1974) ***/
	else if cbtype=9 and agexx>=cbage then do ;
		if cbincome<cbthresh3 then floor=(cbfloor1/100)*cbincome ;
		else floor = (cbfloor1/100)*cbthresh3 + (cbfloor2/100)*(cbincome-cbthresh3) ;

		if cbincome<cbthresh1 then cbmax=(cbmaxcr1*cbincome/cbthresh1) 
			+ (cbmaxcr2*(cbthresh1-cbincome)/cbthresh1) ;
		else if cbincome<cbthresh2 then cbmax=cbmaxcr2 ;
		else cbmax=0 ;
		propcred = min(cbmax,max(0,(cbpct1/100)*proptax+(cbrenteq/100)*rentpay-floor)) ;
	end ;

	/*** CBTYPE 12, 26 (KS 1970-72, MD 1975-80, WI 1964-72) ***/
	else if (cbtype=12 or cbtype=26) then do ;
		if cbincome<cbthresh1 then cbpct=cbpct1 ;
		else if cbincome<cbthresh2 then cbpct=
			(cbpct1*(cbincome-cbthresh1)/(cbthresh2-cbthresh1)) 
			+ (cbpct2*(cbthresh2-cbincome)/(cbthresh2-cbthresh1)) ;
		else if cbincome<cbthresh5 then cbpct=cbpct2 ;
		else cbpct=0 ;

		if cbmaxcr2>0 then propbase=min(proptax,cbmaxcr2) ;
			else propbase=proptax ;
		if cbmaxcr2>0 then rentbase=min(rentpay*(cbrenteq/100),cbmaxcr2) ;
			else rentbase=rentpay*(cbrenteq/100) ;
			
		%bracketreader(cbincome, floor, xrate, xbracket, xbracknum) ;

		if agexx>=cbage then propcred=min((cbpct/100)*(propbase+rentbase),cbmaxcr1) ;
		else if agexx<cbage and cbtype=26 then propcred=.5*min((cbpct/100)*(propbase+rentbase),cbmaxcr1) ;
		else propcred=0 ;
	end ;

	/*** CBTYPE 13 (ME 1989-2004) ***/
	else if cbtype=13 and cbincome<xcbthresh1 then do ;
		if xcbmaxcr2>0 then propbase=min(proptax+(cbrenteq/100)*rentpay,xcbmaxcr2) ;
			else propbase=proptax+(cbrenteq/100)*rentpay ;
		pc=min((xcbpct1/100)*min(max(0,propbase-(xcbfloor1/100)*cbincome),
			((xcbfloor2/100)-(xcbfloor1/100))*cbincome)
			+(xcbpct2/100)*max(0,propbase-(xcbfloor2/100)*cbincome),xcbmaxcr1) ;
		if agexx<cbage then propcred=pc ;
		else propcred=max(propcred,pc) ;
	end ;

	/*** CBTYPE 14 (MD 1981-2004) ***/
	else if cbtype=14 then do ;
		
		if cbmaxhome>0 and homeval>0 then propbase=proptax*(min(cbmaxhome,homeval)/homeval) ;
			else propbase=proptax ;
		if (agexx>=cbage or (cbincome<cbthresh1 and kids2>0)) then rentbase=(cbrenteq/100)*rentpay ;
			else rentbase=0 ;

		%bracketreader(cbincome, floor, xrate, xbracket, xbracknum) ;
		propcred=min(max(rentbase-floor,0),cbmaxcr1) ;

		xr1=xr1-xcbthresh1 ; xr2=xr2-xcbthresh2 ; xr3=xr3-xcbthresh3 ; xr4=xr4-xcbthresh4 ; xr5=xr5-xcbthresh5 ;
		%bracketreader(cbincome, floor, xrate, xbracket, xbracknum) ;
		propcred=propcred+min(max(propbase-floor,0),cbmaxcr2) ;
		xr1=xr1+xcbthresh1 ; xr2=xr2+xcbthresh2 ; xr3=xr3+xcbthresh3 ; xr4=xr4+xcbthresh4 ; xr5=xr5+xcbthresh5 ;

	end ;

	/* CBTYPE 16 (MN 1975-2004) */
	else if cbtype=16 then do ;

		if cbmaxhome>0 and homeval>0 then propbase=proptax*(min(cbmaxhome,homeval)/homeval) ;
			else propbase=proptax ;
		if cbmaxrent>0 and rentpay>0 then rentbase=min(rentpay,cbmaxrent) ;
			else rentbase=rentpay ;
		
		if stateyear<1984 then do ;

			if agexx>=cbage then do ;

				if cbincome>=cbthresh2 then cbmax=cbmaxcr2 ;
				else if cbincome<cbthresh1 then cbmax=cbmaxcr1 ;
				else if cbthresh2>cbthresh1 then 
					cbmax=(cbmaxcr1*(cbincome-cbthresh1)/(cbthresh2-cbthresh1)) 
						+ (cbmaxcr2*(cbthresh2-cbincome)/(cbthresh2-cbthresh1)) ;
				else cbmax=0 ;				

				rentbase=rentbase*(cbrenteq/100) ;

				if max(cbfloor1,cbfloor2)>0 then do ;
					if cbincome>=cbthresh4 then floor=(cbfloor2/100)*cbincome ;
					else if cbincome<cbthresh3 then floor=(cbfloor1/100)*cbincome ;
					else if cbthresh4>cbthresh3 then 
						floor=((cbfloor1/100)*cbincome*(cbincome-cbthresh3)/(cbthresh4-cbthresh3)) 
							+ ((cbfloor2/100)*cbincome*(cbthresh4-cbincome)/(cbthresh4-cbthresh3)) ;
					else floor=0 ;
				end ;
				else floor=0 ;

				if cbincome<cbthresh1 then cbpct = cbpct1 ;
				else if cbincome>=cbthresh2 /* and cbincome<cbthresh5 */ then cbpct = cbpct2 ;
				/* else if cbincome>=cbthresh5 then cbpct=0 ; */
				else if cbthresh2>cbthresh1 then
					cbpct = (cbpct1*(cbincome-cbthresh1)/(cbthresh2-cbthresh1)) 
						+ (cbpct2*(cbthresh2-cbincome)/(cbthresh2-cbthresh1)) ;
				else cbpct=0 ;

				propcred = min((cbpct/100)*max(propbase+rentbase-floor,0),cbmax) ;
			end ;
 
			else if agexx<cbage and xcbpct1>0 then do ;

				rentbase=rentbase*(xcbrenteq/100) ;

				if cbincome<xcbthresh1 then cbmax=cbmaxcr1 ;
					else cbmax=cbmaxcr2 ;

				if max(xcbfloor1,xcbfloor2)>0 then do ;
					if cbincome>=xcbthresh4 then floor=(xcbfloor2/100)*cbincome ;
					else if cbincome<xcbthresh3 then floor=(xcbfloor1/100)*cbincome ;
					else if cbthresh4>xcbthresh3 then 
						floor=((xcbfloor1/100)*cbincome*(cbincome-xcbthresh3)/(xcbthresh4-xcbthresh3)) 
							+ ((xcbfloor2/100)*cbincome*(xcbthresh4-cbincome)/(xcbthresh4-xcbthresh3)) ;
					else floor=0 ;
				end ;
				else floor=0 ;

				propcred = min((xcbpct1/100)*max(propbase+rentbase-floor,0),cbmax) ;

			end ;

		end ;

		else if stateyear>=1984 then do ;

			if cbincome>=cbthresh2 then cbmax=cbmaxcr2 ;
			else if cbincome<cbthresh1 then cbmax=cbmaxcr1 ;
			else if cbthresh2>cbthresh1 then 
				cbmax=(cbmaxcr1*(cbincome-cbthresh1)/(cbthresh2-cbthresh1)) 
					+ (cbmaxcr2*(cbthresh2-cbincome)/(cbthresh2-cbthresh1)) ;
			else cbmax=0 ;				

			if max(cbfloor1,cbfloor2)>0 then do ;
				if cbincome>=cbthresh4 then floor=(cbfloor2/100)*cbincome ;
				else if cbincome<cbthresh3 then floor=(cbfloor1/100)*cbincome ;
				else if cbthresh4>cbthresh3 then 
					floor=((cbfloor1/100)*cbincome*(cbincome-cbthresh3)/(cbthresh4-cbthresh3)) 
						+ ((cbfloor2/100)*cbincome*(cbthresh4-cbincome)/(cbthresh4-cbthresh3)) ;
				else floor=0 ;
			end ;
			else floor=0 ;

			if cbincome<cbthresh1 then cbpct = cbpct1 ;
			else if cbincome>=cbthresh2 then cbpct = cbpct2 ;
			else if cbincome>=cbthresh5 then cbpct=0 ;
			else if cbthresh2>cbthresh1 then
				cbpct = (cbpct1*(cbincome-cbthresh1)/(cbthresh2-cbthresh1)) 
					+ (cbpct2*(cbthresh2-cbincome)/(cbthresh2-cbthresh1)) ;
			else cbpct=0 ;

			propcred = min((cbpct/100)*max(propbase-floor,0),cbmax) ;

			rentbase=rentbase*(xcbrenteq/100) ;

			if cbincome>=xcbthresh2 then cbmax=xcbmaxcr2 ;
			else if cbincome<xcbthresh1 then cbmax=xcbmaxcr1 ;
			else if xcbthresh2>xcbthresh1 then 
				cbmax=(xcbmaxcr1*(cbincome-xcbthresh1)/(xcbthresh2-xcbthresh1)) 
					+ (xcbmaxcr2*(xcbthresh2-cbincome)/(xcbthresh2-xcbthresh1)) ;
			else cbmax=0 ;				

			if max(xcbfloor1,xcbfloor2)>0 then do ;
				if cbincome>=xcbthresh4 then floor=(xcbfloor2/100)*cbincome ;
				else if cbincome<xcbthresh3 then floor=(xcbfloor1/100)*cbincome ;
				else if xcbthresh4>xcbthresh3 then 
					floor=((xcbfloor1/100)*cbincome*(cbincome-xcbthresh3)/(xcbthresh4-xcbthresh3)) 
						+ ((xcbfloor2/100)*cbincome*(xcbthresh4-cbincome)/(xcbthresh4-xcbthresh3)) ;
				else floor=0 ;
			end ;
			else floor=0 ;

			if cbincome<xcbthresh1 then cbpct = xcbpct1 ;
			else if cbincome>=xcbthresh2 then cbpct = xcbpct2 ;
			else if cbincome>=xcbthresh5 then cbpct=0 ;
			else if xcbthresh2>xcbthresh1 then
				cbpct = (xcbpct1*(cbincome-xcbthresh1)/(xcbthresh2-xcbthresh1)) 
					+ (xcbpct2*(xcbthresh2-cbincome)/(xcbthresh2-xcbthresh1)) ;
			else cbpct=0 ;

			propcred = propcred + min((cbpct/100)*max(rentbase-floor,0),cbmax) ;

		end ;

	end ;

	/*** CBTYPE 17 (NJ) ***/
	else if cbtype=17 then do ;
		/* homeowners */
		if stateyear>2002 and agexx>=cbage then do ;
			if cbincome<cbthresh1 then do ;
				cbmin=min(proptax,cbmaxcr1) ;
				cbmax=cbmaxcr2 ;
			end ;
			else if cbincome<cbthresh2 then do ;
				cbmin=min(proptax,cbfloor2) ;
				cbmax=cbfloor3 ;
			end ;
			else if cbincome<cbthresh3 then do ;
				cbmin=min(cbfloor4,proptax) ;
				cbmax=cbfloor4 ;
			end ;
			else do ;
				cbmin=0 ;
				cbmax=0 ;
			end ;
			propcred=max(cbmin,min(cbmax,max(0,proptax-(cbfloor1/100)*cbincome))) ;
		end ;
		else if stateyear>2002 and agexx<cbage then do ;
			if cbincome<cbthresh2 then do ;
				cbmin=min(cbfloor2,proptax) ;
				cbmax=cbfloor3 ;
			end ;
			else if cbincome<cbthresh3 then do ;
				cbmin=min(cbfloor4,proptax) ;
				cbmax=min(cbfloor4,proptax) ;
			end ;
			else do ;
				cbmin=0 ;
				cbmax=0 ;
			end ;
			propcred=max(cbmin,min(cbmax,max(0,proptax-(cbfloor1/100)*cbincome))) ;
		end ;
		else if stateyear<=2002 and agexx>=cbage then do ;
			if cbincome<cbthresh1 then do ;
				cbmin=min(cbpct1,proptax) ;
				cbmax=cbmaxcr1 ;
				propcred=max(cbmin,min(cbmax,max(0,proptax-(cbfloor1/100)*cbincome))) ;
			end;
			else if cbincome<cbthresh2 then propcred=min(cbpct1,proptax) ;
			else if cbincome<cbthresh3 then propcred=min(cbpct2,proptax) ;
			else propcred=0 ;
		end ;
		else if stateyear<=2002 and agexx<cbage then do ;
			if cbincome<cbmaxcr2 then propcred=min(proptax,cbmaxcr2) ;
			else propcred=0 ;
		end ;
		/* Renters */
		rentbase=(xcbrenteq/100)*rentpay ;
		if agexx>=cbage then do ;
			if cbincome<xcbthresh1 then do ;
				cbmax=xcbmaxcr1 ;
				cbmin=min(xcbpct1, rentbase) ;
				propcred=propcred+max(cbmin,min(cbmax,max(0,(rentbase+xcbfloor2-(xcbfloor1/100)*cbincome)))) ;
			end ;
			else if cbincome<xcbthresh2 then propcred=propcred+min(xcbpct1,rentbase) ;
			else if cbincome<xcbthresh3 then propcred=propcred+min(xcbpct2,rentbase) ;
		end ;
		else if agexx<cbage and cbincome<xcbthresh4 then propcred=propcred+min(xcbmaxcr2,rentbase) ;
	end ;

	/*** CBTYPE 18 (New Mexico) ***/
	else if cbtype=18 and agexx>=cbage then do ;

		propbase=proptax ;
		rentbase=rentpay*(cbrenteq/100) ;
		cbmax=cbmaxcr1 ;
		if cbincome<cbthresh3 then floor=cbfloor1 ;
		else if cbincome<cbthresh4 then floor=(cbfloor1*(cbincome-cbthresh3)/(cbthresh4-cbthresh3)) 
			+ (cbfloor2*(cbthresh4-cbincome)/(cbthresh4-cbthresh3)) ;
		else if cbincome<cbthresh5 then floor=(cbfloor2*(cbincome-cbthresh4)/(cbthresh5-cbthresh4)) 
			+ (cbfloor3*(cbthresh5-cbincome)/(cbthresh5-cbthresh4)) ;
		else floor=cbfloor3 ;

		pc = min((cbpct1/100)*max(propbase+rentbase-floor,0),cbmax) ;
			
		if cbincome<cbthresh1 then propcred = pc ;
		else if cbincome>=cbthresh2 then propcred = 0 ;
		else if cbthresh2>cbthresh1 then
			propcred = pc*(cbincome-cbthresh1)/(cbthresh2-cbthresh1) ;
		else propcred=0 ;

	end ;

	/*** CBTYPE 19 (Oregon 1973-present) ***/
	else if cbtype=19 then do ;
		if agexx>=cbage then do ;
			if cbincome<cbthresh1 then pc=max(min(rentpay,cbmaxrent)-(cbfloor1/100)*cbincome,0) ;
			else pc=0 ;
			if cbincome<cbthresh1 then propcred=
				max(pc,min((xcbrenteq/100)*rentpay,xcbmaxcr1)+min(proptax,xcbmaxcr2)) ;
			else if cbincome<cbthresh2 then propcred=
				max(pc,min((xcbrenteq/100)*rentpay,xcbmaxcr1*((income-cbthresh1)/(cbthresh2-cbthresh1)))
					+min(proptax,xcbmaxcr2*((income-cbthresh1)/(cbthresh2-cbthresh1)))) ;
			else propcred=pc ;
		end ;
		else if agexx<cbage and year<=1990 then do ;
			if cbincome<cbthresh1 then propcred=
				min((xcbrenteq/100)*rentpay,xcbmaxcr1)+min(proptax,xcbmaxcr2) ;
			else if cbincome<cbthresh2 then propcred=
				min((xcbrenteq/100)*rentpay,xcbmaxcr1*((income-cbthresh1)/(cbthresh2-cbthresh1)))
					+min(proptax,xcbmaxcr2*((income-cbthresh1)/(cbthresh2-cbthresh1))) ;
			else propcred=pc ;
		end ;
		else propcred=0 ;
	end ;

	/*** CBTYPE 20 (PA 1980-1990) ***/
	else if cbtype=20 and agexx>=cbage then do ;
		propbase=proptax ;
		rentbase=rentpay*(cbrenteq/100) ;

		pc = min((cbpct1/100)*(propbase+rentbase),cbmaxcr1) ;
			
		if cbincome<cbthresh1 then propcred = pc ;
		else if cbincome>=cbthresh2 then propcred = 0 ;
		else if cbthresh2>cbthresh1 then
			propcred = pc*(cbincome-cbthresh1)/(cbthresh2-cbthresh1) ;
		else propcred=0 ;

		if cbincome<cbthresh3 then propcred=propcred+cbfloor1 ;
		else if cbincome>= cbthresh4 then propcred=propcred+0 ;
		else if cbthresh4>cbthresh3 then propcred=propcred
			+cbfloor1*((cbincome-cbthresh3)/(cbthresh4-cbthresh3)) ;

	end ;

	/*** CBTYPE 22 (UT 1982-present) ***/
	else if cbtype=22 and agexx>=cbage then do ;

		propbase=proptax ; 
		if cbincome<cbthresh1 then cbmax=cbmaxcr1 ;
		else if cbincome<cbthresh2 then cbmax=
			cbmaxcr1*(cbincome-cbthresh1)/(cbthresh2-cbthresh1) 
			+ cbmaxcr2*(cbthresh2-cbincome)/(cbthresh2-cbthresh1) ;
		else cbmax=0 ;
		propcred=min((cbpct1/100)*propbase,cbmax) ;

		if cbincome<xcbthresh1 then rentbase=(xcbrenteq/100)*rentpay ;
		else if cbincome<xcbthresh2 then rentbase=		
			((xcbrenteq/100)*(cbincome-xcbthresh1)/(xcbthresh2-xcbthresh1) 
			+ (xcbpct2/100)*(xcbthresh2-cbincome)/(xcbthresh2-xcbthresh1))
			*rentpay ;
		if cbincome<xcbthresh1 then cbmax=xcbmaxcr1 ;
		else if cbincome<xcbthresh2 then cbmax=
			xcbmaxcr1*(cbincome-xcbthresh1)/(xcbthresh2-xcbthresh1) 
			+ xcbmaxcr2*(xcbthresh2-cbincome)/(xcbthresh2-xcbthresh1) ;
		else cbmax=0 ;
		propcred=propcred+min(rentbase,cbmax) ;

	end ;

	/*** CBTYPE 23 (VT 1973-present) ***/
	else if cbtype=23 then do ;
		if cbincome<cbthresh3 then floor=(cbfloor1/100)*cbincome ;
		else if cbincome<cbthresh4 then floor=(cbfloor2/100)*cbincome ;
		else if cbincome<cbthresh5 then floor=(cbfloor3/100)*cbincome ;
		else if xcbthresh1>0 and cbincome<xcbthresh1 then floor=(cbfloor4/100)*cbincome ;
		else if xcbthresh1=0 and cbincome>=cbthresh5 then floor=(cbfloor4/100)*cbincome ;
		else floor=(xcbfloor1/100)*cbincome ;
		if cbmaxcr1>0 then cbmax=max(0,cbmaxcr1-(cbpct2/100)*max(0,cbincome-cbmaxcr2)) ;
		propcred=min(max(0,proptax+(cbrenteq/100)*rentpay-floor),cbmax) ;
	end ;

	/*** CBTYPE 25 (WY) ***/
	else if cbtype=25 then do ;
		if agexx>=cbage then do ;
			pc = min(proptax,cbmaxcr1) ;
			if cbincome<cbthresh1 then propcred = pc ;
			else if cbincome>=cbthresh2 then propcred = 0 ;
			else if cbthresh2>cbthresh1 then
				propcred = pc*(cbincome-cbthresh1)/(cbthresh2-cbthresh1) ;
			else propcred=0 ;
		end ;
		
		if xcbpct1>0 then do ;
			if cbincome<xcbthresh1 then do ;
				cbpct = xcbpct1 ;
				cbmax=xcbmaxcr1 ;
			end ;
			else if xcbthresh5>0 and cbincome<xcbthresh5 then do ;
				cbpct = xcbpct2 ;
				cbmax=xcbmaxcr2 ;
			end ;
			else do ;
				cbpct=0 ;
				cbmax=0 ;
			end ;
			propcred=propcred+min(cbmax,(cbpct/100)*proptax) ;
		end ;
	
	end ;

	/*** CBTYPE 27 (WV 2001-present) ***/
	else if cbtype=27 and agexx>cbage and cbincome<(cbthresh1+cbthresh2*((filertype="m")+deps)) 
		and homeval>=cbthresh3 then propcred = (max(min(cbthresh4,homeval)-cbthresh3,0)/homeval)*
		proptax ;

	/*** CHOOSE WHICH PROPERTY TAX CREDITS TO INCLUDE ***/
	if ( &cbinclude = 1 ) then do ;
		if cbform=2 or cbform=3 or cbform=5 then propcred=0 ;
		else if (cbform=4 or cbform=6) and rentpay=0 then propcred=0 ;
		else if cbform=7 and agexx<cbage then propcred=0 ;
	end ;
	else if ( &cbinclude = 2 ) then do ;
		if (cbform=2 or cbform=3 or cbform=4 or cbform=5 or cbform=6) and rentpay=0 then propcred=0 ;
		else if cbform=7 and agexx<cbage and rentpay=0 then propcred=0 ;
	end ;

	/*** ADJUST STATE TAX BILL FOR PROPERTY TAX CREDITS ***/
	taxs = taxs - propcred ;

end ;
%mend circuit ; 
%if &cbinclude > 0 %then %circuit ;


%mend statetax1 ; 

%macro statetax2 ;
	/********************************************************************************************************** 
	Run the state tax calculator once for states where itemization status is not constrained by
	federal itemization status (itemiz<2).	Run the state tax calculator twice (once for each federal 
	itemizing status) for states where itemization status is constrained in some way by federal itemizing status,
	or where state AMT is a percentage of federal AMT (mintaxtype=5).  The actual federal itemization status 
	is used the second time through.  The difference in state tax liabilities between the two federal itemization 
	statuses is then fed back into the federal tax caclulator in the next iteration.

	If taxnodetail=0, the fourth iteration of the state tax calculator takes federal itemization status as given, 
	so it is not necessary to execute statetax1 twice for that one. If taxnodetail>0, there are two extra iterations,
	so statetax1 is executed twice on the fourth and fifth iterations and then just once on the sixth iteration.

	taxsFNI = state tax liability if taking standard deduction at federal level
	taxsFYI = state tax liability if itemizing at federal level
	Federal variables fed into the state tax calculator are marked with an "_S" suffix.
	***********************************************************************************************************/
	/* Initialize certain variables that will be fed into this iteration of the tax calculator to their values 
	at the end of the previous statetax iteration */
		taxs_S = taxs ;
		taxs1_S = taxs1 ;
		taxs2_S = taxs2 ;
		itemded_S = itemded ;
		itemded1_S = itemded1 ;
		itemded2_S = itemded2 ;

		/* First iteration of statetax1 */

		/* For first run of statetax1, set certain variables equal to their values under sub-optimal federal
	   itemization status for states where itemiz>1 or mintaxtype=5 */
		if (itemiz>1 or mintaxtype=5) and (deductcycle<4 or (deductcycle<6 and taxnodetail>0)) then do ;
			Fitemizer_S = 1-Fitemizer ;
			taxf_S = taxfSI ;
			Ftaxpref_S = FtaxprefSI ;
			Famtpref_S = FamtprefSI ;
			Famt_S = FamtSI ;
			FtaxMIN_S = FtaxMINSI ;
			Famti_S = FamtiSI ;
			Fdtxliab_bc_S = Fdtxliab_bcSI ;
			Fti_S = FtiSI ;
			FmtrNORM_S = FmtrNORMSI ;
			Fkidcred_S = FkidcredSI ;
			Fkidcredref_S = FkidcredrefSI ;

			if taxnodetail>0 then do ;
				if deductcycle=1 then tax_nonincome_S = tax_nonincomeA ;
				else if deductcycle=2 then tax_nonincome_S = tax_nonincomeB ;
				else if deductcycle=3 then tax_nonincome_S = tax_nonincomeC ;
				else tax_nonincome_S = tax_nonincomeD ;
			end ;
			else tax_nonincome_S = 0 ;

			if iteration>1 then do ;
				if deductcycle=1 then do ;
					itemizer_sCONSTANT = itemizer_sFSIA ;
					itemizerSEPCONSTANT = itemizerSEPFSIA ;
					xitemizer_sCONSTANT = xitemizer_sFSIA ;
					SMINitemizerCONSTANT = SMINitemizerFSIA ;
					SMINitemizerSEPCONSTANT = SMINitemizerSEPFSIA ;	
				end ;
				else if deductcycle=2 then do ;
					itemizer_sCONSTANT = itemizer_sFSIB ;
					itemizerSEPCONSTANT = itemizerSEPFSIB ;
					xitemizer_sCONSTANT = xitemizer_sFSIB ;
					SMINitemizerCONSTANT = SMINitemizerFSIB ;
					SMINitemizerSEPCONSTANT = SMINitemizerSEPFSIB ;	
				end ;
				else if deductcycle=3 then do ;
					itemizer_sCONSTANT = itemizer_sFSIC ;
					itemizerSEPCONSTANT = itemizerSEPFSIC ;
					xitemizer_sCONSTANT = xitemizer_sFSIC ;
					SMINitemizerCONSTANT = SMINitemizerFSIC ;
					SMINitemizerSEPCONSTANT = SMINitemizerSEPFSIC ;	
				end ;
				else if deductcycle=4 and taxnodetail>0 then do ;
					itemizer_sCONSTANT = itemizer_sFSID ;
					itemizerSEPCONSTANT = itemizerSEPFSID ;
					xitemizer_sCONSTANT = xitemizer_sFSID ;
					SMINitemizerCONSTANT = SMINitemizerFSID ;
					SMINitemizerSEPCONSTANT = SMINitemizerSEPFSID ;	
				end ;
				else if deductcycle=4 and taxnodetail>0 then do ;
					itemizer_sCONSTANT = itemizer_sFSIE ;
					itemizerSEPCONSTANT = itemizerSEPFSIE ;
					xitemizer_sCONSTANT = xitemizer_sFSIE ;
					SMINitemizerCONSTANT = SMINitemizerFSIE ;
					SMINitemizerSEPCONSTANT = SMINitemizerSEPFSIE ;	
				end ;
			end ;
		end ;
		/* For other states, select certain variables to their values under optimal federal itemization status */
		else do ;
			Fitemizer_S = Fitemizer ;
			taxf_S = taxf ;
			Ftaxpref_S = Ftaxpref ;
			Famtpref_S = Famtpref ;
			Famt_S = Famt ;
			FtaxMIN_S = FtaxMIN ;
			Famti_S = Famti ;
			Fdtxliab_bc_S = Fdtxliab_bc ;
			Fti_S = Fti ;
			FmtrNORM_S = FmtrNORM ;
			Fkidcred_S = Fkidcred ;
			Fkidcredref_S = Fkidcredref ;

			if taxnodetail>0 then do ;
				if deductcycle=1 then tax_nonincome_S = tax_nonincomeA ;
				else if deductcycle=2 then tax_nonincome_S = tax_nonincomeB ;
				else if deductcycle=3 then tax_nonincome_S = tax_nonincomeC ;
				else tax_nonincome_S = tax_nonincomeD ;
			end ;
			else tax_nonincome_S = 0 ;

			if iteration>1 then do ;
				if deductcycle=1 then do ;
					itemizer_sCONSTANT = itemizer_sA ;
					itemizerSEPCONSTANT = itemizerSEPA ;
					xitemizer_sCONSTANT = xitemizer_sA ;
					SMINitemizerCONSTANT = SMINitemizerA ;
					SMINitemizerSEPCONSTANT = SMINitemizerSEPA ;	
				end ;
				else if deductcycle=2 then do ;
					itemizer_sCONSTANT = itemizer_sB ;
					itemizerSEPCONSTANT = itemizerSEPB ;
					xitemizer_sCONSTANT = xitemizer_sB ;
					SMINitemizerCONSTANT = SMINitemizerB ;
					SMINitemizerSEPCONSTANT = SMINitemizerSEPB ;	
				end ;
				else if deductcycle=3 then do ;
					itemizer_sCONSTANT = itemizer_sC ;
					itemizerSEPCONSTANT = itemizerSEPC ;
					xitemizer_sCONSTANT = xitemizer_sC ;
					SMINitemizerCONSTANT = SMINitemizerC ;
					SMINitemizerSEPCONSTANT = SMINitemizerSEPC ;	
				end ;
				else if deductcycle=4 then do ;
					itemizer_sCONSTANT = itemizer_sD ;
					itemizerSEPCONSTANT = itemizerSEPD ;
					xitemizer_sCONSTANT = xitemizer_sD ;
					SMINitemizerCONSTANT = SMINitemizerD ;
					SMINitemizerSEPCONSTANT = SMINitemizerSEPD ;	
				end ;
				else if deductcycle=5 then do ;
					itemizer_sCONSTANT = itemizer_sE ;
					itemizerSEPCONSTANT = itemizerSEPE ;
					xitemizer_sCONSTANT = xitemizer_sE ;
					SMINitemizerCONSTANT = SMINitemizerE ;
					SMINitemizerSEPCONSTANT = SMINitemizerSEPE ;	
				end ;
				else if deductcycle=6 then do ;
					itemizer_sCONSTANT = itemizer_sF ;
					itemizerSEPCONSTANT = itemizerSEPF ;
					xitemizer_sCONSTANT = xitemizer_sF ;
					SMINitemizerCONSTANT = SMINitemizerF ;
					SMINitemizerSEPCONSTANT = SMINitemizerSEPF ;	
				end ;
			end ;
		end ;
		/* Calculate state taxes */
		%statetax1 ;
		/* Set values of key variables fed into future iterations of federal and state calculators */
		taxsFSI = taxs ;
		if (itemiz>1 or mintaxtype=5) and (deductcycle < 4 or (deductcycle<6 and taxnodetail>0)) then do ;
			if Fitemizer_S = 0 then taxsFNI = taxs ;
			else taxsFYI = taxs ;
			if iteration=1 then do ;
				if deductcycle=1 then do ;
					itemizer_sFSIA = itemizer_s ;
					itemizerSEPFSIA = itemizerSEP ;
					xitemizer_sFSIA = xitemizer_s ;
					SMINitemizerFSIA = SMINitemizer ;
					SMINitemizerSEPFSIA = SMINitemizerSEP ;
				end ;
				else if deductcycle=2 then do ;
					itemizer_sFSIB = itemizer_s ;
					itemizerSEPFSIB = itemizerSEP ;
					xitemizer_sFSIB = xitemizer_s ;
					SMINitemizerFSIB = SMINitemizer ;
					SMINitemizerSEPFSIB = SMINitemizerSEP ;
				end ;
				else if deductcycle=3 then do ;
					itemizer_sFSIC = itemizer_s ;
					itemizerSEPFSIC = itemizerSEP ;
					xitemizer_sFSIC = xitemizer_s ;
					SMINitemizerFSIC = SMINitemizer ;
					SMINitemizerSEPFSIC = SMINitemizerSEP ;
				end ;
				else if deductcycle=4 and taxnodetail>0 then do ;
					itemizer_sFSID = itemizer_s ;
					itemizerSEPFSID = itemizerSEP ;
					xitemizer_sFSID = xitemizer_s ;
					SMINitemizerFSID = SMINitemizer ;
					SMINitemizerSEPFSID = SMINitemizerSEP ;
				end ;
				else if deductcycle=4 and taxnodetail>0 then do ;
					itemizer_sFSIE = itemizer_s ;
					itemizerSEPFSIE = itemizerSEP ;
					xitemizer_sFSIE = xitemizer_s ;
					SMINitemizerFSIE = SMINitemizer ;
					SMINitemizerSEPFSIE = SMINitemizerSEP ;
				end ;
			end ;
		end ;
		else do ;
			taxsFNI = taxs ;
			taxsFYI = taxs ;
		end ;

		/* Second iteration of statetax1, run only if itemiz>1 or mintaxtype=5, and deductcycle < 4 
		(or <5 and taxnodetail>0), this time setting variables equal to their values under optimal 
		federal itemization status */
		if (itemiz>1 or mintaxtype=5) and ((deductcycle < 4) or (deductcycle<6 and taxnodetail>0)) then do ;
			Fitemizer_S = Fitemizer ;
			taxf_S = taxf ;
			Ftaxpref_S = Ftaxpref ;
			Famtpref_S = Famtpref ;
			Famt_S = Famt ;
			FtaxMIN_S = FtaxMIN ;
			Famti_S = Famti ;
			Fdtxliab_bc_S = Fdtxliab_bc ;
			Fti_S = Fti ;
			FmtrNORM_S = FmtrNORM ;
			Fkidcred_S = Fkidcred ;
			Fkidcredref_S = Fkidcredref ;

			if taxnodetail>0 then do ;
				if deductcycle=1 then tax_nonincome_S = tax_nonincomeA ;
				else if deductcycle=2 then tax_nonincome_S = tax_nonincomeB ;
				else if deductcycle>2 then tax_nonincome_S = tax_nonincomeC ;
			end ;
			else tax_nonincome_S = 0 ;

			if iteration>1 then do ;
				if deductcycle=1 then do ;
					itemizer_sCONSTANT = itemizer_sA ;
					itemizerSEPCONSTANT = itemizerSEPA ;
					xitemizer_sCONSTANT = xitemizer_sA ;
					SMINitemizerCONSTANT = SMINitemizerA ;
					SMINitemizerSEPCONSTANT = SMINitemizerSEPA ;	
				end ;
				else if deductcycle=2 then do ;
					itemizer_sCONSTANT = itemizer_sB ;
					itemizerSEPCONSTANT = itemizerSEPB ;
					xitemizer_sCONSTANT = xitemizer_sB ;
					SMINitemizerCONSTANT = SMINitemizerB ;
					SMINitemizerSEPCONSTANT = SMINitemizerSEPB ;	
				end ;
				else if deductcycle=3 then do ;
					itemizer_sCONSTANT = itemizer_sC ;
					itemizerSEPCONSTANT = itemizerSEPC ;
					xitemizer_sCONSTANT = xitemizer_sC ;
					SMINitemizerCONSTANT = SMINitemizerC ;
					SMINitemizerSEPCONSTANT = SMINitemizerSEPC ;	
				end ;
				else if deductcycle=4 then do ;
					itemizer_sCONSTANT = itemizer_sD ;
					itemizerSEPCONSTANT = itemizerSEPD ;
					xitemizer_sCONSTANT = xitemizer_sD ;
					SMINitemizerCONSTANT = SMINitemizerD ;
					SMINitemizerSEPCONSTANT = SMINitemizerSEPD ;	
				end ;
				else if deductcycle=5 then do ;
					itemizer_sCONSTANT = itemizer_sE ;
					itemizerSEPCONSTANT = itemizerSEPE ;
					xitemizer_sCONSTANT = xitemizer_sE ;
					SMINitemizerCONSTANT = SMINitemizerE ;
					SMINitemizerSEPCONSTANT = SMINitemizerSEPE ;	
				end ;
			end ;
			%statetax1 ;
			if Fitemizer_S = 0 then taxsFNI = taxs ;
			else taxsFYI = taxs ;
		end ;		
	
%mend statetax2 ;
%statetax2 ; 

 
%mend statetax ; 

/*****************************************************************************************
*                               END OF STATETAX                                          *
/*****************************************************************************************/


/***************************************************************************************
*                  F.   OUTDAT MACRO: WRITES OUTPUT DATA SETS                          *
****************************************************************************************/

/* concise output, text file */

%macro OutDat ;


%macro TextOutput ;

	data _NULL_ ;
   		set TaxResults ;
    		file resultsf(&outputset..csv) lrecl=500 dsd ;
    		put
        	id statename soi year stateyear fedyear
        	tax taxf taxs taxsi sstax
        	mtr mtrf mtrfns mtrfb mtrfbsp
        	mtrs mtrsb mtrsbsp mtrsi ssmtr
        	atr atrf atrs atrsi ssatr income /* weight */ ;
	run ;
 
%mend TextOutput ;

/* concise output, SAS file */

%macro SasOutput ;

	data results.&outputset ;
        set TaxResults ;
        keep
        id statename soi year stateyear fedyear
        tax taxf taxs taxsi sstax
        mtr mtrf mtrfns mtrfb mtrfbsp
        mtrs mtrsb mtrsbsp mtrsi ssmtr
        atr atrf atrs atrsi ssatr income /* weight */ ;
	run;
 
%mend SasOutput ;

%macro SasOutput2 ;

	data &outputset ;
        set TaxResults ;
        keep
        id statename soi year stateyear fedyear
        tax taxf taxs taxsi sstax
        mtr mtrf mtrfns mtrfb mtrfbsp
        mtrs mtrsb mtrsbsp mtrsi ssmtr
        atr atrf atrs atrsi ssatr income /* weight */ ;
	run;
 
%mend SasOutput2 ;

%if &detail = 0 %then %do ;
	%if &outputformat = 0 %then %TextOutput ;
	%else %if &outputformat = 1 %then %SasOutput ;
	%else %if &outputformat = 2 %then %SasOutput2 ;
%end ;

/* detailed output */
%macro TaxDetail ;
	/* When debugging, it is sometimes useful to sort by marginal tax rate,
	which makes it easier to identify anomalies */
	* proc sort data= TaxResults ;
	* by mtr ;

  	%if &outputformat = 0 %then %do ;
  	  data _NULL_ ;
  		set TaxResults ;
    	file resultsf(&outputset..csv) dsd lrecl=3200 ;
    	put
        id statename soi year stateyear fedyear
		filertype deps kids1 kids2 kids3 agenum age agesp blind income 
		wagsal1 wagsal2 businc1 businc2 farminc1 farminc2
		ltcg1 ltcg2 othcg1 othcg2 div1 div2 int1 int2 teint1 teint2 
		pension1 pension2 rentinc1 rentinc2 ui1 ui2 ssben1 ssben2 
		partscorp1 partscorp2 othinc1 othinc2 othadj1 othadj2 
		charity charcg intpaid invint stinctax proptax salestax 
		taxnodetail medexp casualty movex busex miscdedlim omiscded 
		childcare fdcred otaxpref oamtadj avglaginc psincome psded rentpay homeval
        tax taxf taxs taxsi sstax mtr mtrf mtrfns mtrfb mtrfbsp
        mtrs mtrsb mtrsbsp mtrsi ssmtr atr atrf atrs atrsi ssatr
		increment iteration taxf_1 taxf_2 taxfns_1 taxfns_2 
		taxs_1 taxs_2 taxsFDED_1 taxsFDED_2 Fagi_1 Fagi_2 Fssagi_1 Fssagi_2  	
		Fti_1 Fti_2 Fti1_1 Fti1_2 Fti2_1 Fti2_2
		Fsepfiler_1 Fsepfiler_2	Fexempt_1 Fexempt_2 
		Fstded_1 Fstded_2 Fitemded_1 Fitemded_2 
		Fitemizer_1 Fitemizer_2	Fitemlost_1 Fitemlost_2
		Fidmaxlim_1 Fidmaxlim_2	FtaxNORM_1 FtaxNORM_2 
		FtaxMAXEI_1 FtaxMAXEI_2	FtaxALTCG_1 FtaxALTCG_2
		FtaxINCAVG_1 FtaxINCAVG_2 FmtrMEI_1 FmtrMEI_2
		Fdtxliab_bc_1 Fdtxliab_bc_2	FtaxMIN_1 FtaxMIN_2
		Famt_1 Famt_2 Famtpref_1 Famtpref_2
		Famti_1 Famti_2	Famtexempt_1 Famtexempt_2
		Famtiae_1 Famtiae_2	FamtiaeEXCG_1 FamtiaeEXCG_2
		Ftamt_1 Ftamt_2	Fkcarecred_1 Fkcarecred_2
		Feic_1 Feic_2 Fkidcred_1 Fkidcred_2
		Fkidcredref_1 Fkidcredref_2	Feldcred_1 
		Feldcred_2 Fsstxliab_1 Fsstxliab_2
		FsstxliabSE1_1 FsstxliabSE1_2 FsstxliabSE2_1 FsstxliabSE2_2
		agi_1 agi_2	agi1_1 agi1_2 agi2_1 agi2_2
		Sti_1 Sti_2	Sti1_1 Sti1_2 Sti2_1 Sti2_2
		Ssepfiler_1 Ssepfiler_1	exempt_1 exempt_2
		exempt1_1 exempt1_2	exempt2_1 exempt2_2
		stded_1 stded_2	itemded_1 itemded_2
		itemded1_1 itemded1_2 itemded2_1 itemded2_2
		itemizer_s_1 itemizer_s_2 retexamt_1 retexamt_2
		lowexamt_1 retexamt_2 miscex_1 miscex_2
		StaxNORM_1 StaxNORM_2 sptxliab_1 sptxliab_2
		sptx2liab_1 sptx2liab_2	StaxALTCG_1 StaxALTCG_2
		StaxASP_1 StaxASP_2	StaxAMIN_1 StaxAMIN_2
		StaxMIN_1 StaxMIN_2	gencred_1 gencred_2
		retcred_1 retcred_2	retcredref_1 retcredref_2
		lowcred_1 lowcred_2	lowcredref_1 lowcredref_2
		marcred_1 marcred_2	kcarecred_1 kcarecred_2
		StaxAGC_1 StaxAGC_2	xtaxs_1 xtaxs_2
		xcredit_1 xcredit_2	StaxAX_1 StaxAX_2
		eicstateref_1 eicstateref_2	eicstatenoref_1 eicstatenoref_2
		propcred_1 propcred_2 localtax_1 localtax_2 Ftaxtype taxtype 
		Fchlimbind_1 Fchlimbind_2 chlimbind_1 chlimbind_2 mintaxtype Fzba ;
	  run ;
    %end ;

    %else %if &outputformat = 1 %then %do ;
  	  data results.&outputset ;
  		set TaxResults ;
	  run ;
    %end ;

    %else %if &outputformat = 2 %then %do ;
  	  data &outputset ;
  		set TaxResults ;
	  run ;
    %end ;


%mend TaxDetail ; 

%if &detail > 0 %then %TaxDetail ;

%mend OutDat ;  

/*****************************************************************************************
*                               END OF OUTDAT                                            *
******************************************************************************************/


/****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************													*********************
***************** 	G.  INVOKE MACROS CONTAINED IN INCTAXCALC		********************* 
*****************	        IN THE APPROPRIATE ORDER				*********************
*****************													*********************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************/
  %macro InvokeMacros ;

	%MakeData ;
	%Iteration1 ; 
	%if &detail > 0 %then %Detail1 ;
	%if &incrementquantity = 0 %then %NoMTR ;
		%else %MTRcalc ;
	%CloseDataStep ;
	%OutDat ;

  %mend InvokeMacros ;
  %InvokeMacros ;	

options source ;

%mend IncTaxCalc ; 

/****************************************************************************************
*                             END OF INCTAXCALC MACRO 									*	
*****************************************************************************************/

/****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************													*********************
***************** 	VI. SPECIFY OPTIONS, RUN INCTAXCALC MACRO		********************* 
*****************													*********************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************

At the very end of the program (below), the "IncTaxCalc" macro is invoked, which 
effectively runs the whole tax calculation program. Users can name the input and output 
data sets and paths, choose how marginal tax rates are calculated, choose whether to 
produce a detailed output data set, and choose the formats of the input and output data 
sets by changing the "parameters" in the macro below.

The IncTaxCalc macro parameter names are the the terms to the left of the equals signs 
in the parentheses immediately following %IncTaxCalc below. The user enters the value
desired for each parameter to the right of the equals sign. The parameters
are:

programpath			Pathname where program and federal and state tax law parameter data
					sets are stored.

inputpath			Pathname where data on individual taxpayers are stored.

outputpath			Pathname where output data sets containing calculated tax rates,
					tax liabilities, and details of tax caclulation are sent.		

inputset			Name of input data set with individual taxpayer information. Do
					not include any file extension.

outputset 			Name of output data set containing calculated tax rates, tax
					liabilities, and details of tax calculation are sent. Do not 
					include any file extension.

fedparam			Name of data set containing parameters of federal law. Do not include
					file extension. For baseline federal tax parameters use IncTaxFed.

stateparam			Name of data set containing parameters of state law. Do not include
					file extension. For baseline state tax parameters use IncTaxState.

loadparam			Specify whether to load the federal and state tax law parameter 
					text data sets.
					0 = No, do not load the text tax law parameter data sets. Choose this 
					option if you have already run the IncTaxCalc macro at least once 
					during this SAS session. In that case, the program will just read 
					the temporary SAS data sets for federal and state tax law parameters 
					in the working directory.
					1 = Yes, do load the text tax law parameter data sets. Do this if
					this is the first time you are running IncTaxCalc during this SAS session,
					or if you want to change the tax law parameters.

mtrvar				The marginal tax rate is calculated with respect to the variable
					specified in mtrvar.  Any income or deduction variable in the input 
					data set can be used.  

incrementkind 		Type of marginal tax rate increment. The marginal tax rate is
					calculated by adding an increment to the income component or deduction 
					chosen in mtrvar above. The increment can be either a fixed dollar 
					amount (incrementkind=dollar), or a percentage of income 
					(incrementkind=incpct). If the latter is chosen, the increment applied 
					will be the maximum of (incpct/100)*income or $0.10, to deal with 
					situations where income is non-positive.

incrementquantity	Size of increment used to calculate marginal tax rate. If
					incrementkind=dollar, then put the dollar amount here. If 
					incrementkind=incpct, then put the percentage here (e.g., if increment 
					is 10% of income then write 10). If incrementquantity = 0 the calculator 
					will not perform marginal rate calculations.  If you do not need marginal 
					tax rates, the incrementquantity = 0 option will save you some time because
					it will reduce the number of iterations that the calculator performs.

detail 				Indicator for whether to produce an output file containing only the 
					basic tax results, or an output file containing the details of the tax calculations.
					0 = Produce basic output data set.
					1 = Produce detailed output data set.
					2 = Produce detailed output data set, plus create a separate file containing the values
					of all variables at the end of each iteration of federal or state tax calculation. 
					Note that the code implementing this is normally commented out of the program, so that 
					choosing detail = 2 will just produce the same results as detail = 1 unless the user goes 
					into the program and removes the relevant comment lines (which all uniquely include the 
					term "save all variables from all iterations").

inputformat 		Format of input data set. 
					0 = Tab delimited text
					1 = Permanent SAS data set
					2 = Temporary SAS data set in working directory. If this option is chosen,
					the program will assume that the data set specified in "inputset" above
					is a temporary SAS data set in the working directory, and will ignore
					"inputpath".  Choosing this option can speed processing a bit if your "inputset"
					is already in working memory.

outputformat		Format of output data set. 
					0 = Comma delimited	text file 
					1 = Permanent SAS data set.
					2 = Temporary SAS data set. If this option is chosen, a temporary SAS data 
						set is written to the working directory, and outputpath above is ignored.

reverseMTR 			Optional alternative marginal tax rate calculation to eliminate
					notches. If set to 0, marginal tax rate will be calculated simply by 
					adding an increment. If it is set to 1, then marginal tax rates will be 
					computed first by adding an increment to the initial value, and then, 
					if the absolute value of the marginal rate is greater than the value of 
					checkMTR below, it will be calculated again by subtracting the increment 
					from the initial value. Results will be reported for the case where the 
					overall marginal tax rate is smallest in absolute value. 

checkMTR 			Absolute value of marginal tax rate, expressed as a decimal, above
					which the "reverseMTR" calculation described above will be performed.

statecodetype 		Type of state code in input data set. 
					0 = Two-letter postal abrreviation. 
					1 = IRS Statistics of Income 2-digit numeric code.

yearstart			Earliest year of federal or state tax parameter data needed. Setting
					this to a later year can speed processing time.

cbinclude			Include circuit breaker property tax credits in income tax calculation?
					Note that this requires information on property tax for non-itemizers,
					rent, and in a few cases home value.
					0 = Ignore all circuit breaker property tax credits
					1 = Only include circuit breakers that are implemented through the income tax
					2 = Include circuit breakers that are implemented through the income tax,
					plus any rent circuit breakers that are not on the income tax form.
					3 = Include all circuit breakers including those that have nothing to
					do with the income tax.

local				Include local income taxes?  Warning: currently, the tax calculator
					only allows for a very a rough approximation of local income taxes, 
					and only for 1977 an later years.  See documentation for the variables 
					localrate and localtype.
					0 = Do not calculate local income tax bill
					1 = Calculate local income tax bill
					2 = Calculate local income tax bill only for states that have significant local income
					taxes that apply throughout the state (Indiana, Maryland, and Pennsylvania).  Note that 
					local tax calculations for these states are considerably more accurate than for other states.

*************************************************************************************************/
/************************************************************************************************
Example of how to run this program using the SAS Autocall facility:
(1) Create a directory C:\SASmacros
(2) Copy IncTaxCalc.sas into C:\SASmacros, making sure to comment out the next section
(3) In the SAS program where you want to call the IncTaxCalc macro,
    include the following lines on top:

		filename macs "c:\SASmacros" ;
		options mautosource ;
		options sasautos=macs ;

(4) Call the IncTaxCalc macro in your program just as you would with any other
    SAS macro.
**************************************************************************************************/

/* To change names of input or output data sets, the way marginal tax rates are calculated, or
the level of detail in output data sets, change the values to the right of the equal signs below.
See above for further information */

/* Note: the code below calls the IncTaxCalc macro, which effectively runs the whole
tax calculator program.  Comment this out when: (a) debugging, or (b) if this file is to be
saved as a macro and then called using the SAS Autocall facility (see above) */

* %IncTaxCalc(
programpath=C:\Bakija\IncTaxCalc\program,
inputpath=C:\Bakija\IncTaxCalc\indata,
outputpath=C:\data\migration06,
inputset=MidpointInc_M, 
outputset=MPapr06mCAPGAIN,
fedparam=IncTaxFed,
stateparam=IncTaxState,
loadparam=1,
mtrvar=ltcg1,
incrementkind=dollar,
incrementquantity=0.1, 
detail=0,
inputformat=2,
outputformat=1,
reverseMTR=1,
checkMTR=0.9,
statecodetype=0,
yearstart=1970,
cbinclude=1, 
local=1 ) ;

/**************************************************************************************
*                            END OF INCTAXCALC.SAS                                                                        *
***************************************************************************************/
